moving unit tests from .testsuite -> .orm
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class SimpleMapScope implements Scope, Serializable {
|
||||
|
||||
private final Map map = new HashMap();
|
||||
|
||||
private final List callbacks = new LinkedList();
|
||||
|
||||
|
||||
public SimpleMapScope() {
|
||||
}
|
||||
|
||||
public final Map getMap() {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
|
||||
public Object get(String name, ObjectFactory objectFactory) {
|
||||
synchronized (this.map) {
|
||||
Object scopedObject = this.map.get(name);
|
||||
if (scopedObject == null) {
|
||||
scopedObject = objectFactory.getObject();
|
||||
this.map.put(name, scopedObject);
|
||||
}
|
||||
return scopedObject;
|
||||
}
|
||||
}
|
||||
|
||||
public Object remove(String name) {
|
||||
synchronized (this.map) {
|
||||
return this.map.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerDestructionCallback(String name, Runnable callback) {
|
||||
this.callbacks.add(callback);
|
||||
}
|
||||
|
||||
public Object resolveContextualObject(String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
for (Iterator it = this.callbacks.iterator(); it.hasNext();) {
|
||||
Runnable runnable = (Runnable) it.next();
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
public String getConversationId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBeanTests$FilterTestLocalSessionFactoryBean">
|
||||
<property name="filterDefinitions">
|
||||
<list>
|
||||
<bean class="org.springframework.orm.hibernate3.FilterDefinitionFactoryBean">
|
||||
<property name="filterName" value="filter1"/>
|
||||
<property name="parameterTypes">
|
||||
<props>
|
||||
<prop key="param1">string</prop>
|
||||
<prop key="otherParam">long</prop>
|
||||
</props>
|
||||
</property>
|
||||
<property name="defaultFilterCondition" value="someCondition"/>
|
||||
</bean>
|
||||
<bean id="filter2" class="org.springframework.orm.hibernate3.FilterDefinitionFactoryBean">
|
||||
<property name="parameterTypes">
|
||||
<props>
|
||||
<prop key="myParam">integer</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,630 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.hibernate3.support;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.transaction.Status;
|
||||
import javax.transaction.Synchronization;
|
||||
import javax.transaction.TransactionManager;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.easymock.MockControl;
|
||||
import org.easymock.internal.ArrayMatcher;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.classic.Session;
|
||||
|
||||
import org.springframework.jdbc.support.lob.LobCreator;
|
||||
import org.springframework.jdbc.support.lob.LobHandler;
|
||||
import org.springframework.orm.hibernate3.SessionFactoryUtils;
|
||||
import org.springframework.transaction.MockJtaTransaction;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 05.03.2005
|
||||
*/
|
||||
public class LobTypeTests extends TestCase {
|
||||
|
||||
private MockControl rsControl = MockControl.createControl(ResultSet.class);
|
||||
private ResultSet rs = (ResultSet) rsControl.getMock();
|
||||
private MockControl psControl = MockControl.createControl(PreparedStatement.class);
|
||||
private PreparedStatement ps = (PreparedStatement) psControl.getMock();
|
||||
|
||||
private MockControl lobHandlerControl = MockControl.createControl(LobHandler.class);
|
||||
private LobHandler lobHandler = (LobHandler) lobHandlerControl.getMock();
|
||||
private MockControl lobCreatorControl = MockControl.createControl(LobCreator.class);
|
||||
private LobCreator lobCreator = (LobCreator) lobCreatorControl.getMock();
|
||||
|
||||
protected void setUp() throws SQLException {
|
||||
lobHandler.getLobCreator();
|
||||
lobHandlerControl.setReturnValue(lobCreator);
|
||||
lobCreator.close();
|
||||
lobCreatorControl.setVoidCallable(1);
|
||||
|
||||
rsControl.replay();
|
||||
psControl.replay();
|
||||
}
|
||||
|
||||
public void testClobStringType() throws Exception {
|
||||
lobHandler.getClobAsString(rs, "column");
|
||||
lobHandlerControl.setReturnValue("content");
|
||||
lobCreator.setClobAsString(ps, 1, "content");
|
||||
lobCreatorControl.setVoidCallable(1);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
ClobStringType type = new ClobStringType(lobHandler, null);
|
||||
assertEquals(1, type.sqlTypes().length);
|
||||
assertEquals(Types.CLOB, type.sqlTypes()[0]);
|
||||
assertEquals(String.class, type.returnedClass());
|
||||
assertTrue(type.equals("content", "content"));
|
||||
assertEquals("content", type.deepCopy("content"));
|
||||
assertFalse(type.isMutable());
|
||||
|
||||
assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
try {
|
||||
type.nullSafeSet(ps, "content", 1);
|
||||
List synchs = TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(1, synchs.size());
|
||||
assertTrue(synchs.get(0).getClass().getName().endsWith("SpringLobCreatorSynchronization"));
|
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion();
|
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
public void testClobStringTypeWithSynchronizedSession() throws Exception {
|
||||
MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
Session session = (Session) sessionControl.getMock();
|
||||
sf.openSession();
|
||||
sfControl.setReturnValue(session, 1);
|
||||
session.getSessionFactory();
|
||||
sessionControl.setReturnValue(sf, 1);
|
||||
session.close();
|
||||
sessionControl.setReturnValue(null, 1);
|
||||
sfControl.replay();
|
||||
sessionControl.replay();
|
||||
|
||||
lobHandler.getClobAsString(rs, "column");
|
||||
lobHandlerControl.setReturnValue("content");
|
||||
lobCreator.setClobAsString(ps, 1, "content");
|
||||
lobCreatorControl.setVoidCallable(1);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
ClobStringType type = new ClobStringType(lobHandler, null);
|
||||
assertEquals(1, type.sqlTypes().length);
|
||||
assertEquals(Types.CLOB, type.sqlTypes()[0]);
|
||||
assertEquals(String.class, type.returnedClass());
|
||||
assertTrue(type.equals("content", "content"));
|
||||
assertEquals("content", type.deepCopy("content"));
|
||||
assertFalse(type.isMutable());
|
||||
|
||||
assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
try {
|
||||
SessionFactoryUtils.getSession(sf, true);
|
||||
type.nullSafeSet(ps, "content", 1);
|
||||
List synchs = TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(2, synchs.size());
|
||||
assertTrue(synchs.get(0).getClass().getName().endsWith("SpringLobCreatorSynchronization"));
|
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion();
|
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
((TransactionSynchronization) synchs.get(1)).beforeCompletion();
|
||||
((TransactionSynchronization) synchs.get(1)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
|
||||
sfControl.verify();
|
||||
sessionControl.verify();
|
||||
}
|
||||
|
||||
public void testClobStringTypeWithFlushOnCommit() throws Exception {
|
||||
lobHandler.getClobAsString(rs, "column");
|
||||
lobHandlerControl.setReturnValue("content");
|
||||
lobCreator.setClobAsString(ps, 1, "content");
|
||||
lobCreatorControl.setVoidCallable(1);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
ClobStringType type = new ClobStringType(lobHandler, null);
|
||||
assertEquals(1, type.sqlTypes().length);
|
||||
assertEquals(Types.CLOB, type.sqlTypes()[0]);
|
||||
assertEquals(String.class, type.returnedClass());
|
||||
assertTrue(type.equals("content", "content"));
|
||||
assertEquals("content", type.deepCopy("content"));
|
||||
assertFalse(type.isMutable());
|
||||
|
||||
assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
try {
|
||||
type.nullSafeSet(ps, "content", 1);
|
||||
List synchs = TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(1, synchs.size());
|
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
public void testClobStringTypeWithJtaSynchronization() throws Exception {
|
||||
MockControl tmControl = MockControl.createControl(TransactionManager.class);
|
||||
TransactionManager tm = (TransactionManager) tmControl.getMock();
|
||||
MockJtaTransaction transaction = new MockJtaTransaction();
|
||||
tm.getStatus();
|
||||
tmControl.setReturnValue(Status.STATUS_ACTIVE, 1);
|
||||
tm.getTransaction();
|
||||
tmControl.setReturnValue(transaction, 1);
|
||||
|
||||
lobHandler.getClobAsString(rs, "column");
|
||||
lobHandlerControl.setReturnValue("content");
|
||||
lobCreator.setClobAsString(ps, 1, "content");
|
||||
lobCreatorControl.setVoidCallable(1);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
ClobStringType type = new ClobStringType(lobHandler, tm);
|
||||
assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
tmControl.replay();
|
||||
type.nullSafeSet(ps, "content", 1);
|
||||
Synchronization synch = transaction.getSynchronization();
|
||||
assertNotNull(synch);
|
||||
synch.beforeCompletion();
|
||||
synch.afterCompletion(Status.STATUS_COMMITTED);
|
||||
tmControl.verify();
|
||||
}
|
||||
|
||||
public void testClobStringTypeWithJtaSynchronizationAndRollback() throws Exception {
|
||||
MockControl tmControl = MockControl.createControl(TransactionManager.class);
|
||||
TransactionManager tm = (TransactionManager) tmControl.getMock();
|
||||
MockJtaTransaction transaction = new MockJtaTransaction();
|
||||
tm.getStatus();
|
||||
tmControl.setReturnValue(Status.STATUS_ACTIVE, 1);
|
||||
tm.getTransaction();
|
||||
tmControl.setReturnValue(transaction, 1);
|
||||
|
||||
lobHandler.getClobAsString(rs, "column");
|
||||
lobHandlerControl.setReturnValue("content");
|
||||
lobCreator.setClobAsString(ps, 1, "content");
|
||||
lobCreatorControl.setVoidCallable(1);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
ClobStringType type = new ClobStringType(lobHandler, tm);
|
||||
assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
tmControl.replay();
|
||||
type.nullSafeSet(ps, "content", 1);
|
||||
Synchronization synch = transaction.getSynchronization();
|
||||
assertNotNull(synch);
|
||||
synch.afterCompletion(Status.STATUS_ROLLEDBACK);
|
||||
tmControl.verify();
|
||||
}
|
||||
|
||||
public void testBlobStringType() throws Exception {
|
||||
String content = "content";
|
||||
byte[] contentBytes = content.getBytes();
|
||||
lobHandler.getBlobAsBytes(rs, "column");
|
||||
lobHandlerControl.setReturnValue(contentBytes);
|
||||
lobCreator.setBlobAsBytes(ps, 1, contentBytes);
|
||||
lobCreatorControl.setMatcher(new ArrayMatcher());
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobStringType type = new BlobStringType(lobHandler, null);
|
||||
assertEquals(1, type.sqlTypes().length);
|
||||
assertEquals(Types.BLOB, type.sqlTypes()[0]);
|
||||
assertEquals(String.class, type.returnedClass());
|
||||
assertTrue(type.equals("content", "content"));
|
||||
assertEquals("content", type.deepCopy("content"));
|
||||
assertFalse(type.isMutable());
|
||||
|
||||
assertEquals(content, type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
try {
|
||||
type.nullSafeSet(ps, content, 1);
|
||||
List synchs = TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(1, synchs.size());
|
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion();
|
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
public void testBlobStringTypeWithNull() throws Exception {
|
||||
lobHandler.getBlobAsBytes(rs, "column");
|
||||
lobHandlerControl.setReturnValue(null);
|
||||
lobCreator.setBlobAsBytes(ps, 1, null);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobStringType type = new BlobStringType(lobHandler, null);
|
||||
assertEquals(null, type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
try {
|
||||
type.nullSafeSet(ps, null, 1);
|
||||
List synchs = TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(1, synchs.size());
|
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion();
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
public void testBlobStringTypeWithJtaSynchronization() throws Exception {
|
||||
MockControl tmControl = MockControl.createControl(TransactionManager.class);
|
||||
TransactionManager tm = (TransactionManager) tmControl.getMock();
|
||||
MockJtaTransaction transaction = new MockJtaTransaction();
|
||||
tm.getStatus();
|
||||
tmControl.setReturnValue(Status.STATUS_ACTIVE, 1);
|
||||
tm.getTransaction();
|
||||
tmControl.setReturnValue(transaction, 1);
|
||||
|
||||
String content = "content";
|
||||
byte[] contentBytes = content.getBytes();
|
||||
lobHandler.getBlobAsBytes(rs, "column");
|
||||
lobHandlerControl.setReturnValue(contentBytes);
|
||||
lobCreator.setBlobAsBytes(ps, 1, contentBytes);
|
||||
lobCreatorControl.setMatcher(new ArrayMatcher());
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobStringType type = new BlobStringType(lobHandler, tm);
|
||||
assertEquals(content, type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
tmControl.replay();
|
||||
type.nullSafeSet(ps, content, 1);
|
||||
Synchronization synch = transaction.getSynchronization();
|
||||
assertNotNull(synch);
|
||||
synch.beforeCompletion();
|
||||
synch.afterCompletion(Status.STATUS_COMMITTED);
|
||||
tmControl.verify();
|
||||
}
|
||||
|
||||
public void testBlobStringTypeWithJtaSynchronizationAndRollback() throws Exception {
|
||||
MockControl tmControl = MockControl.createControl(TransactionManager.class);
|
||||
TransactionManager tm = (TransactionManager) tmControl.getMock();
|
||||
MockJtaTransaction transaction = new MockJtaTransaction();
|
||||
tm.getStatus();
|
||||
tmControl.setReturnValue(Status.STATUS_ACTIVE, 1);
|
||||
tm.getTransaction();
|
||||
tmControl.setReturnValue(transaction, 1);
|
||||
|
||||
String content = "content";
|
||||
byte[] contentBytes = content.getBytes();
|
||||
lobHandler.getBlobAsBytes(rs, "column");
|
||||
lobHandlerControl.setReturnValue(contentBytes);
|
||||
lobCreator.setBlobAsBytes(ps, 1, contentBytes);
|
||||
lobCreatorControl.setMatcher(new ArrayMatcher());
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobStringType type = new BlobStringType(lobHandler, tm);
|
||||
assertEquals(content, type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
tmControl.replay();
|
||||
type.nullSafeSet(ps, content, 1);
|
||||
Synchronization synch = transaction.getSynchronization();
|
||||
assertNotNull(synch);
|
||||
synch.afterCompletion(Status.STATUS_ROLLEDBACK);
|
||||
tmControl.verify();
|
||||
}
|
||||
|
||||
public void testBlobByteArrayType() throws Exception {
|
||||
byte[] content = "content".getBytes();
|
||||
lobHandler.getBlobAsBytes(rs, "column");
|
||||
lobHandlerControl.setReturnValue(content);
|
||||
lobCreator.setBlobAsBytes(ps, 1, content);
|
||||
lobCreatorControl.setVoidCallable(1);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobByteArrayType type = new BlobByteArrayType(lobHandler, null);
|
||||
assertEquals(1, type.sqlTypes().length);
|
||||
assertEquals(Types.BLOB, type.sqlTypes()[0]);
|
||||
assertEquals(byte[].class, type.returnedClass());
|
||||
assertTrue(type.equals(new byte[] {(byte) 255}, new byte[] {(byte) 255}));
|
||||
assertTrue(Arrays.equals(new byte[] {(byte) 255}, (byte[]) type.deepCopy(new byte[] {(byte) 255})));
|
||||
assertTrue(type.isMutable());
|
||||
|
||||
assertEquals(content, type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
try {
|
||||
type.nullSafeSet(ps, content, 1);
|
||||
List synchs = TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(1, synchs.size());
|
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion();
|
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
public void testBlobByteArrayTypeWithJtaSynchronization() throws Exception {
|
||||
MockControl tmControl = MockControl.createControl(TransactionManager.class);
|
||||
TransactionManager tm = (TransactionManager) tmControl.getMock();
|
||||
MockJtaTransaction transaction = new MockJtaTransaction();
|
||||
tm.getStatus();
|
||||
tmControl.setReturnValue(Status.STATUS_ACTIVE, 1);
|
||||
tm.getTransaction();
|
||||
tmControl.setReturnValue(transaction, 1);
|
||||
|
||||
byte[] content = "content".getBytes();
|
||||
lobHandler.getBlobAsBytes(rs, "column");
|
||||
lobHandlerControl.setReturnValue(content);
|
||||
lobCreator.setBlobAsBytes(ps, 1, content);
|
||||
lobCreatorControl.setVoidCallable(1);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobByteArrayType type = new BlobByteArrayType(lobHandler, tm);
|
||||
assertEquals(content, type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
tmControl.replay();
|
||||
type.nullSafeSet(ps, content, 1);
|
||||
Synchronization synch = transaction.getSynchronization();
|
||||
assertNotNull(synch);
|
||||
synch.beforeCompletion();
|
||||
synch.afterCompletion(Status.STATUS_COMMITTED);
|
||||
tmControl.verify();
|
||||
}
|
||||
|
||||
public void testBlobByteArrayTypeWithJtaSynchronizationAndRollback() throws Exception {
|
||||
MockControl tmControl = MockControl.createControl(TransactionManager.class);
|
||||
TransactionManager tm = (TransactionManager) tmControl.getMock();
|
||||
MockJtaTransaction transaction = new MockJtaTransaction();
|
||||
tm.getStatus();
|
||||
tmControl.setReturnValue(Status.STATUS_ACTIVE, 1);
|
||||
tm.getTransaction();
|
||||
tmControl.setReturnValue(transaction, 1);
|
||||
|
||||
byte[] content = "content".getBytes();
|
||||
lobHandler.getBlobAsBytes(rs, "column");
|
||||
lobHandlerControl.setReturnValue(content);
|
||||
lobCreator.setBlobAsBytes(ps, 1, content);
|
||||
lobCreatorControl.setVoidCallable(1);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobByteArrayType type = new BlobByteArrayType(lobHandler, tm);
|
||||
assertEquals(content, type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
tmControl.replay();
|
||||
type.nullSafeSet(ps, content, 1);
|
||||
Synchronization synch = transaction.getSynchronization();
|
||||
assertNotNull(synch);
|
||||
synch.afterCompletion(Status.STATUS_ROLLEDBACK);
|
||||
tmControl.verify();
|
||||
}
|
||||
|
||||
public void testBlobSerializableType() throws Exception {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject("content");
|
||||
oos.close();
|
||||
|
||||
lobHandler.getBlobAsBinaryStream(rs, "column");
|
||||
lobHandlerControl.setReturnValue(new ByteArrayInputStream(baos.toByteArray()));
|
||||
lobCreator.setBlobAsBytes(ps, 1, baos.toByteArray());
|
||||
lobCreatorControl.setMatcher(new ArrayMatcher());
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobSerializableType type = new BlobSerializableType(lobHandler, null);
|
||||
assertEquals(1, type.sqlTypes().length);
|
||||
assertEquals(Types.BLOB, type.sqlTypes()[0]);
|
||||
assertEquals(Serializable.class, type.returnedClass());
|
||||
assertTrue(type.isMutable());
|
||||
|
||||
assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
try {
|
||||
type.nullSafeSet(ps, "content", 1);
|
||||
List synchs = TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(1, synchs.size());
|
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion();
|
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
public void testBlobSerializableTypeWithNull() throws Exception {
|
||||
lobHandler.getBlobAsBinaryStream(rs, "column");
|
||||
lobHandlerControl.setReturnValue(null);
|
||||
lobCreator.setBlobAsBytes(ps, 1, null);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobSerializableType type = new BlobSerializableType(lobHandler, null);
|
||||
assertEquals(null, type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
try {
|
||||
type.nullSafeSet(ps, null, 1);
|
||||
List synchs = TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(1, synchs.size());
|
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion();
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
public void testBlobSerializableTypeWithJtaSynchronization() throws Exception {
|
||||
MockControl tmControl = MockControl.createControl(TransactionManager.class);
|
||||
TransactionManager tm = (TransactionManager) tmControl.getMock();
|
||||
MockJtaTransaction transaction = new MockJtaTransaction();
|
||||
tm.getStatus();
|
||||
tmControl.setReturnValue(Status.STATUS_ACTIVE, 1);
|
||||
tm.getTransaction();
|
||||
tmControl.setReturnValue(transaction, 1);
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject("content");
|
||||
oos.close();
|
||||
|
||||
lobHandler.getBlobAsBinaryStream(rs, "column");
|
||||
lobHandlerControl.setReturnValue(new ByteArrayInputStream(baos.toByteArray()));
|
||||
lobCreator.setBlobAsBytes(ps, 1, baos.toByteArray());
|
||||
lobCreatorControl.setMatcher(new ArrayMatcher());
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobSerializableType type = new BlobSerializableType(lobHandler, tm);
|
||||
assertEquals(1, type.sqlTypes().length);
|
||||
assertEquals(Types.BLOB, type.sqlTypes()[0]);
|
||||
assertEquals(Serializable.class, type.returnedClass());
|
||||
assertTrue(type.isMutable());
|
||||
|
||||
assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
tmControl.replay();
|
||||
type.nullSafeSet(ps, "content", 1);
|
||||
Synchronization synch = transaction.getSynchronization();
|
||||
assertNotNull(synch);
|
||||
synch.beforeCompletion();
|
||||
synch.afterCompletion(Status.STATUS_COMMITTED);
|
||||
tmControl.verify();
|
||||
}
|
||||
|
||||
public void testBlobSerializableTypeWithJtaSynchronizationAndRollback() throws Exception {
|
||||
MockControl tmControl = MockControl.createControl(TransactionManager.class);
|
||||
TransactionManager tm = (TransactionManager) tmControl.getMock();
|
||||
MockJtaTransaction transaction = new MockJtaTransaction();
|
||||
tm.getStatus();
|
||||
tmControl.setReturnValue(Status.STATUS_ACTIVE, 1);
|
||||
tm.getTransaction();
|
||||
tmControl.setReturnValue(transaction, 1);
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject("content");
|
||||
oos.close();
|
||||
|
||||
lobHandler.getBlobAsBinaryStream(rs, "column");
|
||||
lobHandlerControl.setReturnValue(new ByteArrayInputStream(baos.toByteArray()));
|
||||
lobCreator.setBlobAsBytes(ps, 1, baos.toByteArray());
|
||||
lobCreatorControl.setMatcher(new ArrayMatcher());
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobSerializableType type = new BlobSerializableType(lobHandler, tm);
|
||||
assertEquals(1, type.sqlTypes().length);
|
||||
assertEquals(Types.BLOB, type.sqlTypes()[0]);
|
||||
assertEquals(Serializable.class, type.returnedClass());
|
||||
assertTrue(type.isMutable());
|
||||
|
||||
assertEquals("content", type.nullSafeGet(rs, new String[] {"column"}, null));
|
||||
tmControl.replay();
|
||||
type.nullSafeSet(ps, "content", 1);
|
||||
Synchronization synch = transaction.getSynchronization();
|
||||
assertNotNull(synch);
|
||||
synch.afterCompletion(Status.STATUS_ROLLEDBACK);
|
||||
tmControl.verify();
|
||||
}
|
||||
|
||||
public void testHbm2JavaStyleInitialization() throws Exception {
|
||||
rsControl.reset();
|
||||
psControl.reset();
|
||||
lobHandlerControl.reset();
|
||||
lobCreatorControl.reset();
|
||||
|
||||
ClobStringType cst = null;
|
||||
BlobByteArrayType bbat = null;
|
||||
BlobSerializableType bst = null;
|
||||
try {
|
||||
cst = new ClobStringType();
|
||||
bbat = new BlobByteArrayType();
|
||||
bst = new BlobSerializableType();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
fail("Should not have thrown exception on initialization");
|
||||
}
|
||||
|
||||
try {
|
||||
cst.nullSafeGet(rs, new String[] {"column"}, null);
|
||||
fail("Should have thrown IllegalStateException");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
bbat.nullSafeGet(rs, new String[] {"column"}, null);
|
||||
fail("Should have thrown IllegalStateException");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
bst.nullSafeGet(rs, new String[] {"column"}, null);
|
||||
fail("Should have thrown IllegalStateException");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
protected void tearDown() {
|
||||
try {
|
||||
rsControl.verify();
|
||||
psControl.verify();
|
||||
lobHandlerControl.verify();
|
||||
lobCreatorControl.verify();
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
// ignore: test method didn't call replay
|
||||
}
|
||||
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
|
||||
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,631 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.hibernate3.support;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Ignore;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 05.03.2005
|
||||
*/
|
||||
@Ignore // getting errors on mocks
|
||||
public class OpenSessionInViewTests extends TestCase {
|
||||
|
||||
// public void testOpenSessionInViewInterceptorWithSingleSession() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
|
||||
// rawInterceptor.setSessionFactory(sf);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf, 2);
|
||||
// session.isOpen();
|
||||
// sessionControl.setReturnValue(true, 1);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
//
|
||||
// // check that further invocations simply participate
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// assertEquals(session, SessionFactoryUtils.getSession(sf, false));
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewInterceptorWithSingleSessionAndJtaTm() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactoryImplementor.class);
|
||||
// final SessionFactoryImplementor sf = (SessionFactoryImplementor) sfControl.getMock();
|
||||
// MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// MockControl tmControl = MockControl.createControl(TransactionManager.class);
|
||||
// TransactionManager tm = (TransactionManager) tmControl.getMock();
|
||||
// tm.getTransaction();
|
||||
// tmControl.setReturnValue(null, 2);
|
||||
//
|
||||
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
|
||||
// rawInterceptor.setSessionFactory(sf);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// sf.getTransactionManager();
|
||||
// sfControl.setReturnValue(tm, 2);
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.isOpen();
|
||||
// sessionControl.setReturnValue(true, 1);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
//
|
||||
// tmControl.replay();
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
//
|
||||
// // check that further invocations simply participate
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// assertEquals(session, SessionFactoryUtils.getSession(sf, false));
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewInterceptorWithSingleSessionAndFlush() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
|
||||
// rawInterceptor.setSessionFactory(sf);
|
||||
// rawInterceptor.setFlushMode(HibernateAccessor.FLUSH_AUTO);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
// session.flush();
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewInterceptorAndDeferredClose() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
|
||||
// rawInterceptor.setSessionFactory(sf);
|
||||
// rawInterceptor.setSingleSession(false);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf, 1);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
|
||||
// SessionFactoryUtils.releaseSession(sess, sf);
|
||||
//
|
||||
// // check that further invocations simply participate
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// sfControl.reset();
|
||||
// sessionControl.reset();
|
||||
//
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewFilterWithSingleSession() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// MockControl sf2Control = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf2 = (SessionFactory) sf2Control.getMock();
|
||||
// MockControl session2Control = MockControl.createControl(Session.class);
|
||||
// Session session2 = (Session) session2Control.getMock();
|
||||
//
|
||||
// sf2.openSession();
|
||||
// sf2Control.setReturnValue(session2, 1);
|
||||
// session2.getSessionFactory();
|
||||
// session2Control.setReturnValue(sf);
|
||||
// session2.setFlushMode(FlushMode.AUTO);
|
||||
// session2Control.setVoidCallable(1);
|
||||
// session2.close();
|
||||
// session2Control.setReturnValue(null, 1);
|
||||
// sf2Control.replay();
|
||||
// session2Control.replay();
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
// wac.setServletContext(sc);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2);
|
||||
// wac.refresh();
|
||||
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
|
||||
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
|
||||
// filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
|
||||
// filterConfig2.addInitParameter("flushMode", "AUTO");
|
||||
//
|
||||
// final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
|
||||
// filter.init(filterConfig);
|
||||
// final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
|
||||
// filter2.init(filterConfig2);
|
||||
//
|
||||
// final FilterChain filterChain = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// servletRequest.setAttribute("invoked", Boolean.TRUE);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// final FilterChain filterChain2 = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
|
||||
// throws IOException, ServletException {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf2));
|
||||
// filter.doFilter(servletRequest, servletResponse, filterChain);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
|
||||
//
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf2));
|
||||
// filter2.doFilter(request, response, filterChain3);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf));
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(sf2));
|
||||
// assertNotNull(request.getAttribute("invoked"));
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// sf2Control.verify();
|
||||
// session2Control.verify();
|
||||
//
|
||||
// wac.close();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewFilterWithSingleSessionAndPreBoundSession() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
// wac.setServletContext(sc);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
|
||||
// wac.refresh();
|
||||
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
|
||||
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
|
||||
// filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
|
||||
//
|
||||
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
|
||||
// rawInterceptor.setSessionFactory(sf);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
|
||||
// filter.init(filterConfig);
|
||||
//
|
||||
// final FilterChain filterChain = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// servletRequest.setAttribute("invoked", Boolean.TRUE);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// filter.doFilter(request, response, filterChain);
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(sf));
|
||||
// assertNotNull(request.getAttribute("invoked"));
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// wac.close();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewFilterWithDeferredClose() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// final MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// final Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf);
|
||||
// session.getFlushMode();
|
||||
// sessionControl.setReturnValue(FlushMode.NEVER, 1);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// MockControl sf2Control = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf2 = (SessionFactory) sf2Control.getMock();
|
||||
// final MockControl session2Control = MockControl.createControl(Session.class);
|
||||
// final Session session2 = (Session) session2Control.getMock();
|
||||
// MockControl txControl = MockControl.createControl(Transaction.class);
|
||||
// Transaction tx = (Transaction) txControl.getMock();
|
||||
// MockControl conControl = MockControl.createControl(Connection.class);
|
||||
// Connection con = (Connection) conControl.getMock();
|
||||
//
|
||||
// sf2.openSession();
|
||||
// sf2Control.setReturnValue(session2, 1);
|
||||
// session2.beginTransaction();
|
||||
// session2Control.setReturnValue(tx, 1);
|
||||
// session2.connection();
|
||||
// session2Control.setReturnValue(con, 2);
|
||||
// tx.commit();
|
||||
// txControl.setVoidCallable(1);
|
||||
// session2.isConnected();
|
||||
// session2Control.setReturnValue(true, 1);
|
||||
// con.isReadOnly();
|
||||
// conControl.setReturnValue(false, 1);
|
||||
// session2.setFlushMode(FlushMode.NEVER);
|
||||
// session2Control.setVoidCallable(1);
|
||||
//
|
||||
// sf2Control.replay();
|
||||
// session2Control.replay();
|
||||
// txControl.replay();
|
||||
// conControl.replay();
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
// wac.setServletContext(sc);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2);
|
||||
// wac.refresh();
|
||||
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
|
||||
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
|
||||
// filterConfig.addInitParameter("singleSession", "false");
|
||||
// filterConfig2.addInitParameter("singleSession", "false");
|
||||
// filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
|
||||
//
|
||||
// final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
|
||||
// filter.init(filterConfig);
|
||||
// final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
|
||||
// filter2.init(filterConfig2);
|
||||
//
|
||||
// final FilterChain filterChain = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
// HibernateTransactionManager tm = new HibernateTransactionManager(sf);
|
||||
// TransactionStatus ts = tm.getTransaction(
|
||||
// new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS));
|
||||
// org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
|
||||
// SessionFactoryUtils.releaseSession(sess, sf);
|
||||
// tm.commit(ts);
|
||||
//
|
||||
// sessionControl.verify();
|
||||
// sessionControl.reset();
|
||||
//
|
||||
// session.close();
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// servletRequest.setAttribute("invoked", Boolean.TRUE);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// final FilterChain filterChain2 = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
|
||||
// throws IOException, ServletException {
|
||||
//
|
||||
// HibernateTransactionManager tm = new HibernateTransactionManager(sf2);
|
||||
// TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
|
||||
// tm.commit(ts);
|
||||
//
|
||||
// session2Control.verify();
|
||||
// session2Control.reset();
|
||||
//
|
||||
// session2.close();
|
||||
// session2Control.setReturnValue(null, 1);
|
||||
// session2Control.replay();
|
||||
//
|
||||
// filter.doFilter(servletRequest, servletResponse, filterChain);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
|
||||
//
|
||||
// filter2.doFilter(request, response, filterChain3);
|
||||
// assertNotNull(request.getAttribute("invoked"));
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
// sf2Control.verify();
|
||||
// session2Control.verify();
|
||||
// txControl.verify();
|
||||
// conControl.verify();
|
||||
//
|
||||
// wac.close();
|
||||
// }
|
||||
//
|
||||
// public void testOpenSessionInViewFilterWithDeferredCloseAndAlreadyActiveDeferredClose() throws Exception {
|
||||
// MockControl sfControl = MockControl.createControl(SessionFactory.class);
|
||||
// final SessionFactory sf = (SessionFactory) sfControl.getMock();
|
||||
// final MockControl sessionControl = MockControl.createControl(Session.class);
|
||||
// final Session session = (Session) sessionControl.getMock();
|
||||
//
|
||||
// sf.openSession();
|
||||
// sfControl.setReturnValue(session, 1);
|
||||
// session.getSessionFactory();
|
||||
// sessionControl.setReturnValue(sf);
|
||||
// session.getFlushMode();
|
||||
// sessionControl.setReturnValue(FlushMode.NEVER, 1);
|
||||
// session.setFlushMode(FlushMode.NEVER);
|
||||
// sessionControl.setVoidCallable(1);
|
||||
// sfControl.replay();
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
// wac.setServletContext(sc);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
|
||||
// wac.refresh();
|
||||
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
|
||||
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
|
||||
// filterConfig.addInitParameter("singleSession", "false");
|
||||
// filterConfig2.addInitParameter("singleSession", "false");
|
||||
// filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
|
||||
//
|
||||
// OpenSessionInViewInterceptor rawInterceptor = new OpenSessionInViewInterceptor();
|
||||
// rawInterceptor.setSessionFactory(sf);
|
||||
// rawInterceptor.setSingleSession(false);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
|
||||
// filter.init(filterConfig);
|
||||
// final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
|
||||
// filter2.init(filterConfig2);
|
||||
//
|
||||
// final FilterChain filterChain = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
// HibernateTransactionManager tm = new HibernateTransactionManager(sf);
|
||||
// TransactionStatus ts = tm.getTransaction(
|
||||
// new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS));
|
||||
// org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
|
||||
// SessionFactoryUtils.releaseSession(sess, sf);
|
||||
// tm.commit(ts);
|
||||
//
|
||||
// sessionControl.verify();
|
||||
// sessionControl.reset();
|
||||
// try {
|
||||
// session.close();
|
||||
// }
|
||||
// catch (HibernateException ex) {
|
||||
// }
|
||||
// sessionControl.setReturnValue(null, 1);
|
||||
// sessionControl.replay();
|
||||
//
|
||||
// servletRequest.setAttribute("invoked", Boolean.TRUE);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// FilterChain filterChain2 = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
|
||||
// throws IOException, ServletException {
|
||||
// filter.doFilter(servletRequest, servletResponse, filterChain);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// filter.doFilter(request, response, filterChain2);
|
||||
// assertNotNull(request.getAttribute("invoked"));
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// sfControl.verify();
|
||||
// sessionControl.verify();
|
||||
//
|
||||
// wac.close();
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBeanTests$TypeTestLocalSessionFactoryBean">
|
||||
<property name="typeDefinitions">
|
||||
<list>
|
||||
<bean class="org.springframework.orm.hibernate3.TypeDefinitionBean">
|
||||
<property name="typeName" value="type1"/>
|
||||
<property name="typeClass" value="mypackage.MyTypeClass"/>
|
||||
<property name="parameters">
|
||||
<props>
|
||||
<prop key="param1">value1</prop>
|
||||
<prop key="otherParam">othervalue</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
<bean id="type2" class="org.springframework.orm.hibernate3.TypeDefinitionBean">
|
||||
<property name="typeName" value="type2"/>
|
||||
<property name="typeClass" value="mypackage.MyOtherTypeClass"/>
|
||||
<property name="parameters">
|
||||
<props>
|
||||
<prop key="myParam">myvalue</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,440 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.ibatis;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient;
|
||||
import com.ibatis.sqlmap.client.SqlMapExecutor;
|
||||
import com.ibatis.sqlmap.client.SqlMapSession;
|
||||
import com.ibatis.sqlmap.client.event.RowHandler;
|
||||
import junit.framework.TestCase;
|
||||
import org.easymock.MockControl;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.JdbcUpdateAffectedIncorrectNumberOfRowsException;
|
||||
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Alef Arendsen
|
||||
* @since 09.10.2004
|
||||
*/
|
||||
public class SqlMapClientTests extends TestCase {
|
||||
|
||||
public void testSqlMapClientFactoryBeanWithoutConfig() throws Exception {
|
||||
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
|
||||
// explicitly set to null, don't know why ;-)
|
||||
factory.setConfigLocation(null);
|
||||
try {
|
||||
factory.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testSqlMapClientTemplate() throws SQLException {
|
||||
MockControl dsControl = MockControl.createControl(DataSource.class);
|
||||
DataSource ds = (DataSource) dsControl.getMock();
|
||||
MockControl conControl = MockControl.createControl(Connection.class);
|
||||
Connection con = (Connection) conControl.getMock();
|
||||
ds.getConnection();
|
||||
dsControl.setReturnValue(con, 1);
|
||||
con.close();
|
||||
conControl.setVoidCallable(1);
|
||||
dsControl.replay();
|
||||
conControl.replay();
|
||||
|
||||
MockControl sessionControl = MockControl.createControl(SqlMapSession.class);
|
||||
final SqlMapSession session = (SqlMapSession) sessionControl.getMock();
|
||||
MockControl clientControl = MockControl.createControl(SqlMapClient.class);
|
||||
SqlMapClient client = (SqlMapClient) clientControl.getMock();
|
||||
client.openSession();
|
||||
clientControl.setReturnValue(session, 1);
|
||||
session.getCurrentConnection();
|
||||
sessionControl.setReturnValue(null, 1);
|
||||
session.setUserConnection(con);
|
||||
sessionControl.setVoidCallable(1);
|
||||
session.close();
|
||||
sessionControl.setVoidCallable(1);
|
||||
sessionControl.replay();
|
||||
clientControl.replay();
|
||||
|
||||
SqlMapClientTemplate template = new SqlMapClientTemplate();
|
||||
template.setDataSource(ds);
|
||||
template.setSqlMapClient(client);
|
||||
template.afterPropertiesSet();
|
||||
Object result = template.execute(new SqlMapClientCallback() {
|
||||
public Object doInSqlMapClient(SqlMapExecutor executor) {
|
||||
assertTrue(executor == session);
|
||||
return "done";
|
||||
}
|
||||
});
|
||||
assertEquals("done", result);
|
||||
dsControl.verify();
|
||||
conControl.verify();
|
||||
sessionControl.verify();
|
||||
clientControl.verify();
|
||||
}
|
||||
|
||||
public void testSqlMapClientTemplateWithNestedSqlMapSession() throws SQLException {
|
||||
MockControl dsControl = MockControl.createControl(DataSource.class);
|
||||
DataSource ds = (DataSource) dsControl.getMock();
|
||||
MockControl conControl = MockControl.createControl(Connection.class);
|
||||
final Connection con = (Connection) conControl.getMock();
|
||||
dsControl.replay();
|
||||
conControl.replay();
|
||||
|
||||
MockControl sessionControl = MockControl.createControl(SqlMapSession.class);
|
||||
final SqlMapSession session = (SqlMapSession) sessionControl.getMock();
|
||||
MockControl clientControl = MockControl.createControl(SqlMapClient.class);
|
||||
SqlMapClient client = (SqlMapClient) clientControl.getMock();
|
||||
client.openSession();
|
||||
clientControl.setReturnValue(session, 1);
|
||||
session.getCurrentConnection();
|
||||
sessionControl.setReturnValue(con, 1);
|
||||
sessionControl.replay();
|
||||
clientControl.replay();
|
||||
|
||||
SqlMapClientTemplate template = new SqlMapClientTemplate();
|
||||
template.setDataSource(ds);
|
||||
template.setSqlMapClient(client);
|
||||
template.afterPropertiesSet();
|
||||
Object result = template.execute(new SqlMapClientCallback() {
|
||||
public Object doInSqlMapClient(SqlMapExecutor executor) {
|
||||
assertTrue(executor == session);
|
||||
return "done";
|
||||
}
|
||||
});
|
||||
assertEquals("done", result);
|
||||
dsControl.verify();
|
||||
conControl.verify();
|
||||
sessionControl.verify();
|
||||
clientControl.verify();
|
||||
}
|
||||
|
||||
public void testQueryForObjectOnSqlMapSession() throws SQLException {
|
||||
MockControl dsControl = MockControl.createControl(DataSource.class);
|
||||
DataSource ds = (DataSource) dsControl.getMock();
|
||||
MockControl conControl = MockControl.createControl(Connection.class);
|
||||
Connection con = (Connection) conControl.getMock();
|
||||
MockControl clientControl = MockControl.createControl(SqlMapClient.class);
|
||||
SqlMapClient client = (SqlMapClient) clientControl.getMock();
|
||||
MockControl sessionControl = MockControl.createControl(SqlMapSession.class);
|
||||
SqlMapSession session = (SqlMapSession) sessionControl.getMock();
|
||||
|
||||
ds.getConnection();
|
||||
dsControl.setReturnValue(con, 1);
|
||||
con.close();
|
||||
conControl.setVoidCallable(1);
|
||||
client.getDataSource();
|
||||
clientControl.setReturnValue(ds, 2);
|
||||
client.openSession();
|
||||
clientControl.setReturnValue(session, 1);
|
||||
session.getCurrentConnection();
|
||||
sessionControl.setReturnValue(null, 1);
|
||||
session.setUserConnection(con);
|
||||
sessionControl.setVoidCallable(1);
|
||||
session.queryForObject("myStatement", "myParameter");
|
||||
sessionControl.setReturnValue("myResult", 1);
|
||||
session.close();
|
||||
sessionControl.setVoidCallable(1);
|
||||
|
||||
dsControl.replay();
|
||||
conControl.replay();
|
||||
clientControl.replay();
|
||||
sessionControl.replay();
|
||||
|
||||
SqlMapClientTemplate template = new SqlMapClientTemplate();
|
||||
template.setSqlMapClient(client);
|
||||
template.afterPropertiesSet();
|
||||
assertEquals("myResult", template.queryForObject("myStatement", "myParameter"));
|
||||
|
||||
dsControl.verify();
|
||||
clientControl.verify();
|
||||
}
|
||||
|
||||
public void testQueryForObject() throws SQLException {
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.queryForObject("myStatement", null);
|
||||
template.executorControl.setReturnValue("myResult", 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals("myResult", template.queryForObject("myStatement"));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testQueryForObjectWithParameter() throws SQLException {
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.queryForObject("myStatement", "myParameter");
|
||||
template.executorControl.setReturnValue("myResult", 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals("myResult", template.queryForObject("myStatement", "myParameter"));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testQueryForObjectWithParameterAndResultObject() throws SQLException {
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.queryForObject("myStatement", "myParameter", "myResult");
|
||||
template.executorControl.setReturnValue("myResult", 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals("myResult", template.queryForObject("myStatement", "myParameter", "myResult"));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testQueryForList() throws SQLException {
|
||||
List result = new ArrayList();
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.queryForList("myStatement", null);
|
||||
template.executorControl.setReturnValue(result, 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals(result, template.queryForList("myStatement"));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testQueryForListWithParameter() throws SQLException {
|
||||
List result = new ArrayList();
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.queryForList("myStatement", "myParameter");
|
||||
template.executorControl.setReturnValue(result, 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals(result, template.queryForList("myStatement", "myParameter"));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testQueryForListWithResultSize() throws SQLException {
|
||||
List result = new ArrayList();
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.queryForList("myStatement", null, 10, 20);
|
||||
template.executorControl.setReturnValue(result, 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals(result, template.queryForList("myStatement", 10, 20));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testQueryForListParameterAndWithResultSize() throws SQLException {
|
||||
List result = new ArrayList();
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.queryForList("myStatement", "myParameter", 10, 20);
|
||||
template.executorControl.setReturnValue(result, 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals(result, template.queryForList("myStatement", "myParameter", 10, 20));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testQueryWithRowHandler() throws SQLException {
|
||||
RowHandler rowHandler = new TestRowHandler();
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.queryWithRowHandler("myStatement", null, rowHandler);
|
||||
template.executorControl.setVoidCallable(1);
|
||||
template.executorControl.replay();
|
||||
template.queryWithRowHandler("myStatement", rowHandler);
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testQueryWithRowHandlerWithParameter() throws SQLException {
|
||||
RowHandler rowHandler = new TestRowHandler();
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.queryWithRowHandler("myStatement", "myParameter", rowHandler);
|
||||
template.executorControl.setVoidCallable(1);
|
||||
template.executorControl.replay();
|
||||
template.queryWithRowHandler("myStatement", "myParameter", rowHandler);
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testQueryForMap() throws SQLException {
|
||||
Map result = new HashMap();
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.queryForMap("myStatement", "myParameter", "myKey");
|
||||
template.executorControl.setReturnValue(result, 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals(result, template.queryForMap("myStatement", "myParameter", "myKey"));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testQueryForMapWithValueProperty() throws SQLException {
|
||||
Map result = new HashMap();
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.queryForMap("myStatement", "myParameter", "myKey", "myValue");
|
||||
template.executorControl.setReturnValue(result, 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals(result, template.queryForMap("myStatement", "myParameter", "myKey", "myValue"));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testInsert() throws SQLException {
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.insert("myStatement", null);
|
||||
template.executorControl.setReturnValue("myResult", 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals("myResult", template.insert("myStatement"));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testInsertWithParameter() throws SQLException {
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.insert("myStatement", "myParameter");
|
||||
template.executorControl.setReturnValue("myResult", 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals("myResult", template.insert("myStatement", "myParameter"));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testUpdate() throws SQLException {
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.update("myStatement", null);
|
||||
template.executorControl.setReturnValue(10, 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals(10, template.update("myStatement"));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testUpdateWithParameter() throws SQLException {
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.update("myStatement", "myParameter");
|
||||
template.executorControl.setReturnValue(10, 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals(10, template.update("myStatement", "myParameter"));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testUpdateWithRequiredRowsAffected() throws SQLException {
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.update("myStatement", "myParameter");
|
||||
template.executorControl.setReturnValue(10, 1);
|
||||
template.executorControl.replay();
|
||||
template.update("myStatement", "myParameter", 10);
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testUpdateWithRequiredRowsAffectedAndInvalidRowCount() throws SQLException {
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.update("myStatement", "myParameter");
|
||||
template.executorControl.setReturnValue(20, 1);
|
||||
template.executorControl.replay();
|
||||
try {
|
||||
template.update("myStatement", "myParameter", 10);
|
||||
fail("Should have thrown JdbcUpdateAffectedIncorrectNumberOfRowsException");
|
||||
}
|
||||
catch (JdbcUpdateAffectedIncorrectNumberOfRowsException ex) {
|
||||
// expected
|
||||
assertEquals(10, ex.getExpectedRowsAffected());
|
||||
assertEquals(20, ex.getActualRowsAffected());
|
||||
}
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testDelete() throws SQLException {
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.delete("myStatement", null);
|
||||
template.executorControl.setReturnValue(10, 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals(10, template.delete("myStatement"));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testDeleteWithParameter() throws SQLException {
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.delete("myStatement", "myParameter");
|
||||
template.executorControl.setReturnValue(10, 1);
|
||||
template.executorControl.replay();
|
||||
assertEquals(10, template.delete("myStatement", "myParameter"));
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testDeleteWithRequiredRowsAffected() throws SQLException {
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.delete("myStatement", "myParameter");
|
||||
template.executorControl.setReturnValue(10, 1);
|
||||
template.executorControl.replay();
|
||||
template.delete("myStatement", "myParameter", 10);
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testDeleteWithRequiredRowsAffectedAndInvalidRowCount() throws SQLException {
|
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate();
|
||||
template.executor.delete("myStatement", "myParameter");
|
||||
template.executorControl.setReturnValue(20, 1);
|
||||
template.executorControl.replay();
|
||||
try {
|
||||
template.delete("myStatement", "myParameter", 10);
|
||||
fail("Should have thrown JdbcUpdateAffectedIncorrectNumberOfRowsException");
|
||||
}
|
||||
catch (JdbcUpdateAffectedIncorrectNumberOfRowsException ex) {
|
||||
// expected
|
||||
assertEquals(10, ex.getExpectedRowsAffected());
|
||||
assertEquals(20, ex.getActualRowsAffected());
|
||||
}
|
||||
template.executorControl.verify();
|
||||
}
|
||||
|
||||
public void testSqlMapClientDaoSupport() throws Exception {
|
||||
MockControl dsControl = MockControl.createControl(DataSource.class);
|
||||
DataSource ds = (DataSource) dsControl.getMock();
|
||||
SqlMapClientDaoSupport testDao = new SqlMapClientDaoSupport() {
|
||||
};
|
||||
testDao.setDataSource(ds);
|
||||
assertEquals(ds, testDao.getDataSource());
|
||||
|
||||
MockControl clientControl = MockControl.createControl(SqlMapClient.class);
|
||||
SqlMapClient client = (SqlMapClient) clientControl.getMock();
|
||||
clientControl.replay();
|
||||
|
||||
testDao.setSqlMapClient(client);
|
||||
assertEquals(client, testDao.getSqlMapClient());
|
||||
|
||||
SqlMapClientTemplate template = new SqlMapClientTemplate();
|
||||
template.setDataSource(ds);
|
||||
template.setSqlMapClient(client);
|
||||
testDao.setSqlMapClientTemplate(template);
|
||||
assertEquals(template, testDao.getSqlMapClientTemplate());
|
||||
|
||||
testDao.afterPropertiesSet();
|
||||
}
|
||||
|
||||
|
||||
private static class TestSqlMapClientTemplate extends SqlMapClientTemplate {
|
||||
|
||||
public MockControl executorControl = MockControl.createControl(SqlMapExecutor.class);
|
||||
public SqlMapExecutor executor = (SqlMapExecutor) executorControl.getMock();
|
||||
|
||||
public Object execute(SqlMapClientCallback action) throws DataAccessException {
|
||||
try {
|
||||
return action.doInSqlMapClient(executor);
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
throw getExceptionTranslator().translate("SqlMapClient operation", null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class TestRowHandler implements RowHandler {
|
||||
|
||||
public void handleRow(Object row) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.ibatis.support;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.easymock.ArgumentsMatcher;
|
||||
import org.easymock.MockControl;
|
||||
|
||||
import org.springframework.jdbc.datasource.DataSourceUtils;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy;
|
||||
import org.springframework.jdbc.support.lob.LobCreator;
|
||||
import org.springframework.jdbc.support.lob.LobHandler;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 27.02.2005
|
||||
*/
|
||||
public class LobTypeHandlerTests extends TestCase {
|
||||
|
||||
private MockControl rsControl = MockControl.createControl(ResultSet.class);
|
||||
private ResultSet rs = (ResultSet) rsControl.getMock();
|
||||
private MockControl psControl = MockControl.createControl(PreparedStatement.class);
|
||||
private PreparedStatement ps = (PreparedStatement) psControl.getMock();
|
||||
|
||||
private MockControl lobHandlerControl = MockControl.createControl(LobHandler.class);
|
||||
private LobHandler lobHandler = (LobHandler) lobHandlerControl.getMock();
|
||||
private MockControl lobCreatorControl = MockControl.createControl(LobCreator.class);
|
||||
private LobCreator lobCreator = (LobCreator) lobCreatorControl.getMock();
|
||||
|
||||
protected void setUp() throws SQLException {
|
||||
rs.findColumn("column");
|
||||
rsControl.setReturnValue(1);
|
||||
|
||||
lobHandler.getLobCreator();
|
||||
lobHandlerControl.setReturnValue(lobCreator);
|
||||
lobCreator.close();
|
||||
lobCreatorControl.setVoidCallable(1);
|
||||
|
||||
rsControl.replay();
|
||||
psControl.replay();
|
||||
}
|
||||
|
||||
public void testClobStringTypeHandler() throws Exception {
|
||||
lobHandler.getClobAsString(rs, 1);
|
||||
lobHandlerControl.setReturnValue("content", 2);
|
||||
lobCreator.setClobAsString(ps, 1, "content");
|
||||
lobCreatorControl.setVoidCallable(1);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
ClobStringTypeHandler type = new ClobStringTypeHandler(lobHandler);
|
||||
assertEquals("content", type.valueOf("content"));
|
||||
assertEquals("content", type.getResult(rs, "column"));
|
||||
assertEquals("content", type.getResult(rs, 1));
|
||||
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
try {
|
||||
type.setParameter(ps, 1, "content", null);
|
||||
List synchs = TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(1, synchs.size());
|
||||
assertTrue(synchs.get(0).getClass().getName().endsWith("LobCreatorSynchronization"));
|
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion();
|
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
public void testClobStringTypeWithSynchronizedConnection() throws Exception {
|
||||
DataSource dsTarget = new DriverManagerDataSource();
|
||||
DataSource ds = new LazyConnectionDataSourceProxy(dsTarget);
|
||||
|
||||
lobHandler.getClobAsString(rs, 1);
|
||||
lobHandlerControl.setReturnValue("content", 2);
|
||||
lobCreator.setClobAsString(ps, 1, "content");
|
||||
lobCreatorControl.setVoidCallable(1);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
ClobStringTypeHandler type = new ClobStringTypeHandler(lobHandler);
|
||||
assertEquals("content", type.valueOf("content"));
|
||||
assertEquals("content", type.getResult(rs, "column"));
|
||||
assertEquals("content", type.getResult(rs, 1));
|
||||
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
try {
|
||||
DataSourceUtils.getConnection(ds);
|
||||
type.setParameter(ps, 1, "content", null);
|
||||
List synchs = TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(2, synchs.size());
|
||||
assertTrue(synchs.get(0).getClass().getName().endsWith("LobCreatorSynchronization"));
|
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion();
|
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
((TransactionSynchronization) synchs.get(1)).beforeCompletion();
|
||||
((TransactionSynchronization) synchs.get(1)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
public void testBlobByteArrayType() throws Exception {
|
||||
byte[] content = "content".getBytes();
|
||||
lobHandler.getBlobAsBytes(rs, 1);
|
||||
lobHandlerControl.setReturnValue(content, 2);
|
||||
lobCreator.setBlobAsBytes(ps, 1, content);
|
||||
lobCreatorControl.setVoidCallable(1);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobByteArrayTypeHandler type = new BlobByteArrayTypeHandler(lobHandler);
|
||||
assertTrue(Arrays.equals(content, (byte[]) type.valueOf("content")));
|
||||
assertEquals(content, type.getResult(rs, "column"));
|
||||
assertEquals(content, type.getResult(rs, 1));
|
||||
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
try {
|
||||
type.setParameter(ps, 1, content, null);
|
||||
List synchs = TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(1, synchs.size());
|
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion();
|
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
public void testBlobSerializableType() throws Exception {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject("content");
|
||||
oos.close();
|
||||
|
||||
lobHandler.getBlobAsBinaryStream(rs, 1);
|
||||
lobHandlerControl.setReturnValue(new ByteArrayInputStream(baos.toByteArray()), 1);
|
||||
lobHandler.getBlobAsBinaryStream(rs, 1);
|
||||
lobHandlerControl.setReturnValue(new ByteArrayInputStream(baos.toByteArray()), 1);
|
||||
lobCreator.setBlobAsBytes(ps, 1, baos.toByteArray());
|
||||
lobCreatorControl.setMatcher(new ArgumentsMatcher() {
|
||||
public boolean matches(Object[] o1, Object[] o2) {
|
||||
return Arrays.equals((byte[]) o1[2], (byte[]) o2[2]);
|
||||
}
|
||||
public String toString(Object[] objects) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobSerializableTypeHandler type = new BlobSerializableTypeHandler(lobHandler);
|
||||
assertEquals("content", type.valueOf("content"));
|
||||
assertEquals("content", type.getResult(rs, "column"));
|
||||
assertEquals("content", type.getResult(rs, 1));
|
||||
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
try {
|
||||
type.setParameter(ps, 1, "content", null);
|
||||
List synchs = TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(1, synchs.size());
|
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion();
|
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
public void testBlobSerializableTypeWithNull() throws Exception {
|
||||
lobHandler.getBlobAsBinaryStream(rs, 1);
|
||||
lobHandlerControl.setReturnValue(null, 2);
|
||||
lobCreator.setBlobAsBytes(ps, 1, null);
|
||||
|
||||
lobHandlerControl.replay();
|
||||
lobCreatorControl.replay();
|
||||
|
||||
BlobSerializableTypeHandler type = new BlobSerializableTypeHandler(lobHandler);
|
||||
assertEquals(null, type.valueOf(null));
|
||||
assertEquals(null, type.getResult(rs, "column"));
|
||||
assertEquals(null, type.getResult(rs, 1));
|
||||
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
try {
|
||||
type.setParameter(ps, 1, null, null);
|
||||
List synchs = TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(1, synchs.size());
|
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion();
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
}
|
||||
|
||||
protected void tearDown() {
|
||||
try {
|
||||
rsControl.verify();
|
||||
psControl.verify();
|
||||
lobHandlerControl.verify();
|
||||
lobCreatorControl.verify();
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
// ignore: test method didn't call replay
|
||||
}
|
||||
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
|
||||
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jdo.support;
|
||||
|
||||
import org.junit.Ignore;
|
||||
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @since 15.06.2004
|
||||
*/
|
||||
@Ignore // dependency issues after moving from .testsuite -> .test
|
||||
public class OpenPersistenceManagerInViewTests {
|
||||
|
||||
// public void testOpenPersistenceManagerInViewInterceptor() throws Exception {
|
||||
// MockControl pmfControl = MockControl.createControl(PersistenceManagerFactory.class);
|
||||
// PersistenceManagerFactory pmf = (PersistenceManagerFactory) pmfControl.getMock();
|
||||
// MockControl pmControl = MockControl.createControl(PersistenceManager.class);
|
||||
// PersistenceManager pm = (PersistenceManager) pmControl.getMock();
|
||||
//
|
||||
// OpenPersistenceManagerInViewInterceptor rawInterceptor = new OpenPersistenceManagerInViewInterceptor();
|
||||
// rawInterceptor.setPersistenceManagerFactory(pmf);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// pmf.getPersistenceManager();
|
||||
// pmfControl.setReturnValue(pm, 1);
|
||||
// pmfControl.replay();
|
||||
// pmControl.replay();
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(pmf));
|
||||
//
|
||||
// // check that further invocations simply participate
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// pmfControl.verify();
|
||||
// pmControl.verify();
|
||||
//
|
||||
// pmfControl.reset();
|
||||
// pmControl.reset();
|
||||
// pmfControl.replay();
|
||||
// pmControl.replay();
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(pmf));
|
||||
// pmfControl.verify();
|
||||
// pmControl.verify();
|
||||
//
|
||||
// pmfControl.reset();
|
||||
// pmControl.reset();
|
||||
// pm.close();
|
||||
// pmControl.setVoidCallable(1);
|
||||
// pmfControl.replay();
|
||||
// pmControl.replay();
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(pmf));
|
||||
// pmfControl.verify();
|
||||
// pmControl.verify();
|
||||
// }
|
||||
//
|
||||
// public void testOpenPersistenceManagerInViewFilter() throws Exception {
|
||||
// MockControl pmfControl = MockControl.createControl(PersistenceManagerFactory.class);
|
||||
// final PersistenceManagerFactory pmf = (PersistenceManagerFactory) pmfControl.getMock();
|
||||
// MockControl pmControl = MockControl.createControl(PersistenceManager.class);
|
||||
// PersistenceManager pm = (PersistenceManager) pmControl.getMock();
|
||||
//
|
||||
// pmf.getPersistenceManager();
|
||||
// pmfControl.setReturnValue(pm, 1);
|
||||
// pm.close();
|
||||
// pmControl.setVoidCallable(1);
|
||||
// pmfControl.replay();
|
||||
// pmControl.replay();
|
||||
//
|
||||
// MockControl pmf2Control = MockControl.createControl(PersistenceManagerFactory.class);
|
||||
// final PersistenceManagerFactory pmf2 = (PersistenceManagerFactory) pmf2Control.getMock();
|
||||
// MockControl pm2Control = MockControl.createControl(PersistenceManager.class);
|
||||
// PersistenceManager pm2 = (PersistenceManager) pm2Control.getMock();
|
||||
//
|
||||
// pmf2.getPersistenceManager();
|
||||
// pmf2Control.setReturnValue(pm2, 1);
|
||||
// pm2.close();
|
||||
// pm2Control.setVoidCallable(1);
|
||||
// pmf2Control.replay();
|
||||
// pm2Control.replay();
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
// wac.setServletContext(sc);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("persistenceManagerFactory", pmf);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("myPersistenceManagerFactory", pmf2);
|
||||
// wac.refresh();
|
||||
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
|
||||
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
|
||||
// filterConfig2.addInitParameter("persistenceManagerFactoryBeanName", "myPersistenceManagerFactory");
|
||||
//
|
||||
// final OpenPersistenceManagerInViewFilter filter = new OpenPersistenceManagerInViewFilter();
|
||||
// filter.init(filterConfig);
|
||||
// final OpenPersistenceManagerInViewFilter filter2 = new OpenPersistenceManagerInViewFilter();
|
||||
// filter2.init(filterConfig2);
|
||||
//
|
||||
// final FilterChain filterChain = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(pmf));
|
||||
// servletRequest.setAttribute("invoked", Boolean.TRUE);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// final FilterChain filterChain2 = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
|
||||
// throws IOException, ServletException {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(pmf2));
|
||||
// filter.doFilter(servletRequest, servletResponse, filterChain);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
|
||||
//
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(pmf));
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(pmf2));
|
||||
// filter2.doFilter(request, response, filterChain3);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(pmf));
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(pmf2));
|
||||
// assertNotNull(request.getAttribute("invoked"));
|
||||
//
|
||||
// pmfControl.verify();
|
||||
// pmControl.verify();
|
||||
// pmf2Control.verify();
|
||||
// pm2Control.verify();
|
||||
//
|
||||
// wac.close();
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
myKey=myValue
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
import javax.persistence.FlushModeType;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.springframework.orm.jpa.domain.DriversLicense;
|
||||
import org.springframework.orm.jpa.domain.Person;
|
||||
import org.springframework.test.annotation.ExpectedException;
|
||||
import org.springframework.test.annotation.NotTransactional;
|
||||
import org.springframework.test.annotation.Repeat;
|
||||
import org.springframework.test.annotation.Timed;
|
||||
|
||||
/**
|
||||
* Integration tests for LocalContainerEntityManagerFactoryBean.
|
||||
* Uses an in-memory database.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public abstract class AbstractContainerEntityManagerFactoryIntegrationTests
|
||||
extends AbstractEntityManagerFactoryIntegrationTests {
|
||||
|
||||
@NotTransactional
|
||||
public void testEntityManagerFactoryImplementsEntityManagerFactoryInfo() {
|
||||
assertTrue(Proxy.isProxyClass(entityManagerFactory.getClass()));
|
||||
assertTrue("Must have introduced config interface",
|
||||
entityManagerFactory instanceof EntityManagerFactoryInfo);
|
||||
EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory;
|
||||
//assertEquals("Person", emfi.getPersistenceUnitName());
|
||||
assertNotNull("PersistenceUnitInfo must be available", emfi.getPersistenceUnitInfo());
|
||||
assertNotNull("Raw EntityManagerFactory must be available", emfi.getNativeEntityManagerFactory());
|
||||
}
|
||||
|
||||
public void testStateClean() {
|
||||
assertEquals("Should be no people from previous transactions",
|
||||
0, countRowsInTable("person"));
|
||||
}
|
||||
|
||||
@Repeat(5)
|
||||
public void testJdbcTx1() throws Exception {
|
||||
testJdbcTx2();
|
||||
}
|
||||
|
||||
@Timed(millis=273)
|
||||
public void testJdbcTx2() throws InterruptedException {
|
||||
//Thread.sleep(2000);
|
||||
assertEquals("Any previous tx must have been rolled back", 0, countRowsInTable("person"));
|
||||
//insertPerson("foo");
|
||||
executeSqlScript("/org/springframework/orm/jpa/insertPerson.sql", false);
|
||||
}
|
||||
|
||||
//@NotTransactional
|
||||
public void testEntityManagerProxyIsProxy() {
|
||||
assertTrue(Proxy.isProxyClass(sharedEntityManager.getClass()));
|
||||
Query q = sharedEntityManager.createQuery("select p from Person as p");
|
||||
List<Person> people = q.getResultList();
|
||||
|
||||
assertTrue("Should be open to start with", sharedEntityManager.isOpen());
|
||||
sharedEntityManager.close();
|
||||
assertTrue("Close should have been silently ignored", sharedEntityManager.isOpen());
|
||||
}
|
||||
|
||||
@ExpectedException(RuntimeException.class)
|
||||
public void testBogusQuery() {
|
||||
Query query = sharedEntityManager.createQuery("It's raining toads");
|
||||
// required in OpenJPA case
|
||||
query.executeUpdate();
|
||||
}
|
||||
|
||||
@ExpectedException(EntityNotFoundException.class)
|
||||
public void testGetReferenceWhenNoRow() {
|
||||
// Fails here with TopLink
|
||||
Person notThere = sharedEntityManager.getReference(Person.class, 666);
|
||||
|
||||
// We may get here (as with Hibernate).
|
||||
// Either behaviour is
|
||||
// valid--throw exception on first access
|
||||
// or on getReference itself
|
||||
notThere.getFirstName();
|
||||
}
|
||||
|
||||
public void testLazyLoading() {
|
||||
try {
|
||||
Person tony = new Person();
|
||||
tony.setFirstName("Tony");
|
||||
tony.setLastName("Blair");
|
||||
tony.setDriversLicense(new DriversLicense("8439DK"));
|
||||
sharedEntityManager.persist(tony);
|
||||
setComplete();
|
||||
endTransaction();
|
||||
|
||||
startNewTransaction();
|
||||
sharedEntityManager.clear();
|
||||
Person newTony = entityManagerFactory.createEntityManager().getReference(Person.class, tony.getId());
|
||||
assertNotSame(newTony, tony);
|
||||
endTransaction();
|
||||
|
||||
assertNotNull(newTony.getDriversLicense());
|
||||
|
||||
newTony.getDriversLicense().getSerialNumber();
|
||||
}
|
||||
finally {
|
||||
deleteFromTables(new String[] { "person", "drivers_license" });
|
||||
//setComplete();
|
||||
}
|
||||
}
|
||||
|
||||
public void testMultipleResults() {
|
||||
// Add with JDBC
|
||||
String firstName = "Tony";
|
||||
insertPerson(firstName);
|
||||
|
||||
assertTrue(Proxy.isProxyClass(sharedEntityManager.getClass()));
|
||||
Query q = sharedEntityManager.createQuery("select p from Person as p");
|
||||
List<Person> people = q.getResultList();
|
||||
|
||||
assertEquals(1, people.size());
|
||||
assertEquals(firstName, people.get(0).getFirstName());
|
||||
}
|
||||
|
||||
protected final void insertPerson(String firstName) {
|
||||
String INSERT_PERSON = "INSERT INTO PERSON (ID, FIRST_NAME, LAST_NAME) VALUES (?, ?, ?)";
|
||||
simpleJdbcTemplate.update(INSERT_PERSON, 1, firstName, "Blair");
|
||||
}
|
||||
|
||||
public void testEntityManagerProxyRejectsProgrammaticTxManagement() {
|
||||
try {
|
||||
sharedEntityManager.getTransaction();
|
||||
fail("Should not be able to create transactions on container managed EntityManager");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testSharedEntityManagerProxyRejectsProgrammaticTxJoining() {
|
||||
try {
|
||||
sharedEntityManager.joinTransaction();
|
||||
fail("Should not be able to join transactions with container managed EntityManager");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
// public void testAspectJInjectionOfConfigurableEntity() {
|
||||
// Person p = new Person();
|
||||
// System.err.println(p);
|
||||
// assertNotNull("Was injected", p.getTestBean());
|
||||
// assertEquals("Ramnivas", p.getTestBean().getName());
|
||||
// }
|
||||
|
||||
public void testInstantiateAndSaveWithSharedEmProxy() {
|
||||
testInstantiateAndSave(sharedEntityManager);
|
||||
}
|
||||
|
||||
protected void testInstantiateAndSave(EntityManager em) {
|
||||
assertEquals("Should be no people from previous transactions",
|
||||
0, countRowsInTable("person"));
|
||||
Person p = new Person();
|
||||
p.setFirstName("Tony");
|
||||
p.setLastName("Blair");
|
||||
em.persist(p);
|
||||
|
||||
em.flush();
|
||||
assertEquals("1 row must have been inserted", 1, countRowsInTable("person"));
|
||||
}
|
||||
|
||||
public void testQueryNoPersons() {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
Query q = em.createQuery("select p from Person as p");
|
||||
List<Person> people = q.getResultList();
|
||||
assertEquals(0, people.size());
|
||||
try {
|
||||
assertNull(q.getSingleResult());
|
||||
fail("Should have thrown NoResultException");
|
||||
}
|
||||
catch (NoResultException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@NotTransactional
|
||||
public void testQueryNoPersonsNotTransactional() {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
Query q = em.createQuery("select p from Person as p");
|
||||
List<Person> people = q.getResultList();
|
||||
assertEquals(0, people.size());
|
||||
try {
|
||||
assertNull(q.getSingleResult());
|
||||
fail("Should have thrown NoResultException");
|
||||
}
|
||||
catch (NoResultException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testQueryNoPersonsShared() {
|
||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(entityManagerFactory);
|
||||
Query q = em.createQuery("select p from Person as p");
|
||||
q.setFlushMode(FlushModeType.AUTO);
|
||||
List<Person> people = q.getResultList();
|
||||
try {
|
||||
assertNull(q.getSingleResult());
|
||||
fail("Should have thrown NoResultException");
|
||||
}
|
||||
catch (NoResultException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@NotTransactional
|
||||
public void testQueryNoPersonsSharedNotTransactional() {
|
||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(entityManagerFactory);
|
||||
Query q = em.createQuery("select p from Person as p");
|
||||
q.setFlushMode(FlushModeType.AUTO);
|
||||
List<Person> people = q.getResultList();
|
||||
assertEquals(0, people.size());
|
||||
try {
|
||||
assertNull(q.getSingleResult());
|
||||
fail("Should have thrown IllegalStateException");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// IllegalStateException expected, but PersistenceException thrown by Hibernate
|
||||
assertTrue(ex.getMessage().indexOf("closed") != -1);
|
||||
}
|
||||
q = em.createQuery("select p from Person as p");
|
||||
q.setFlushMode(FlushModeType.AUTO);
|
||||
try {
|
||||
assertNull(q.getSingleResult());
|
||||
fail("Should have thrown NoResultException");
|
||||
}
|
||||
catch (NoResultException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.spi.PersistenceUnitInfo;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.easymock.MockControl;
|
||||
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* Superclass for unit tests for EntityManagerFactory-creating beans.
|
||||
* Note: Subclasses must set expectations on the mock EntityManagerFactory.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public abstract class AbstractEntityManagerFactoryBeanTests extends TestCase {
|
||||
|
||||
protected static MockControl emfMc;
|
||||
|
||||
protected static EntityManagerFactory mockEmf;
|
||||
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
emfMc = MockControl.createControl(EntityManagerFactory.class);
|
||||
mockEmf = (EntityManagerFactory) emfMc.getMock();
|
||||
}
|
||||
|
||||
protected void checkInvariants(AbstractEntityManagerFactoryBean demf) {
|
||||
assertTrue(EntityManagerFactory.class.isAssignableFrom(demf.getObjectType()));
|
||||
Object gotObject = demf.getObject();
|
||||
assertTrue("Object created by factory implements EntityManagerFactoryInfo",
|
||||
gotObject instanceof EntityManagerFactoryInfo);
|
||||
EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) demf.getObject();
|
||||
assertSame("Successive invocations of getObject() return same object", emfi, demf.getObject());
|
||||
assertSame(emfi, demf.getObject());
|
||||
assertSame(emfi.getNativeEntityManagerFactory(), mockEmf);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
|
||||
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
|
||||
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
|
||||
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
|
||||
}
|
||||
|
||||
|
||||
protected static class DummyEntityManagerFactoryBean extends AbstractEntityManagerFactoryBean {
|
||||
|
||||
private final EntityManagerFactory emf;
|
||||
|
||||
public DummyEntityManagerFactoryBean(EntityManagerFactory emf) {
|
||||
this.emf = emf;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EntityManagerFactory createNativeEntityManagerFactory() throws PersistenceException {
|
||||
return emf;
|
||||
}
|
||||
|
||||
public PersistenceUnitInfo getPersistenceUnitInfo() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public String getPersistenceUnitName() {
|
||||
return "test";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa;
|
||||
|
||||
import org.springframework.test.jpa.AbstractJpaTests;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public abstract class AbstractEntityManagerFactoryIntegrationTests extends AbstractJpaTests {
|
||||
|
||||
public static final String[] TOPLINK_CONFIG_LOCATIONS = new String[] {
|
||||
"/org/springframework/orm/jpa/toplink/toplink-manager.xml", "/org/springframework/orm/jpa/memdb.xml",
|
||||
"/org/springframework/orm/jpa/inject.xml"};
|
||||
|
||||
public static final String[] ECLIPSELINK_CONFIG_LOCATIONS = new String[] {
|
||||
"/org/springframework/orm/jpa/eclipselink/eclipselink-manager.xml", "/org/springframework/orm/jpa/memdb.xml",
|
||||
"/org/springframework/orm/jpa/inject.xml"};
|
||||
|
||||
public static final String[] HIBERNATE_CONFIG_LOCATIONS = new String[] {
|
||||
"/org/springframework/orm/jpa/hibernate/hibernate-manager.xml", "/org/springframework/orm/jpa/memdb.xml",
|
||||
"/org/springframework/orm/jpa/inject.xml"};
|
||||
|
||||
public static final String[] OPENJPA_CONFIG_LOCATIONS = new String[] {
|
||||
"/org/springframework/orm/jpa/openjpa/openjpa-manager.xml", "/org/springframework/orm/jpa/memdb.xml",
|
||||
"/org/springframework/orm/jpa/inject.xml"};
|
||||
|
||||
|
||||
public static Provider getProvider() {
|
||||
String provider = System.getProperty("org.springframework.orm.jpa.provider");
|
||||
if (provider != null) {
|
||||
if (provider.toLowerCase().contains("eclipselink")) {
|
||||
return Provider.ECLIPSELINK;
|
||||
}
|
||||
if (provider.toLowerCase().contains("hibernate")) {
|
||||
return Provider.HIBERNATE;
|
||||
}
|
||||
if (provider.toLowerCase().contains("openjpa")) {
|
||||
return Provider.OPENJPA;
|
||||
}
|
||||
}
|
||||
return Provider.TOPLINK;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getActualOrmXmlLocation() {
|
||||
// Specify that we do NOT want to find such a file.
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
Provider provider = getProvider();
|
||||
switch (provider) {
|
||||
case HIBERNATE:
|
||||
return HIBERNATE_CONFIG_LOCATIONS;
|
||||
case TOPLINK:
|
||||
return TOPLINK_CONFIG_LOCATIONS;
|
||||
case OPENJPA:
|
||||
return OPENJPA_CONFIG_LOCATIONS;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown provider: " + provider);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTearDownAfterTransaction() throws Exception {
|
||||
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
|
||||
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
|
||||
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
|
||||
assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
|
||||
}
|
||||
|
||||
|
||||
public enum Provider {
|
||||
TOPLINK, ECLIPSELINK, HIBERNATE, OPENJPA
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa;
|
||||
|
||||
import java.util.List;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.TransactionRequiredException;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.orm.jpa.domain.Person;
|
||||
import org.springframework.orm.jpa.AbstractEntityManagerFactoryIntegrationTests;
|
||||
import org.springframework.test.annotation.NotTransactional;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* An application-managed entity manager can join an existing transaction,
|
||||
* but such joining must be made programmatically, not transactionally.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ApplicationManagedEntityManagerIntegrationTests extends AbstractEntityManagerFactoryIntegrationTests {
|
||||
|
||||
@NotTransactional
|
||||
public void testEntityManagerIsProxy() {
|
||||
assertTrue("EntityManagerFactory is proxied", Proxy.isProxyClass(entityManagerFactory.getClass()));
|
||||
}
|
||||
|
||||
@Transactional(readOnly=true)
|
||||
public void testEntityManagerProxyIsProxy() {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
assertTrue(Proxy.isProxyClass(em.getClass()));
|
||||
Query q = em.createQuery("select p from Person as p");
|
||||
List<Person> people = q.getResultList();
|
||||
|
||||
assertTrue("Should be open to start with", em.isOpen());
|
||||
em.close();
|
||||
assertFalse("Close should work on application managed EM", em.isOpen());
|
||||
}
|
||||
|
||||
public void testEntityManagerProxyAcceptsProgrammaticTxJoining() {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
em.joinTransaction();
|
||||
}
|
||||
|
||||
public void testInstantiateAndSave() {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
em.joinTransaction();
|
||||
doInstantiateAndSave(em);
|
||||
}
|
||||
|
||||
public void testCannotFlushWithoutGettingTransaction() {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
try {
|
||||
doInstantiateAndSave(em);
|
||||
fail("Should have thrown TransactionRequiredException");
|
||||
}
|
||||
catch (TransactionRequiredException ex) {
|
||||
// expected
|
||||
}
|
||||
|
||||
// TODO following lines are a workaround for Hibernate bug
|
||||
// If Hibernate throws an exception due to flush(),
|
||||
// it actually HAS flushed, meaning that the database
|
||||
// was updated outside the transaction
|
||||
deleteAllPeopleUsingEntityManager(sharedEntityManager);
|
||||
setComplete();
|
||||
}
|
||||
|
||||
public void doInstantiateAndSave(EntityManager em) {
|
||||
testStateClean();
|
||||
Person p = new Person();
|
||||
|
||||
p.setFirstName("Tony");
|
||||
p.setLastName("Blair");
|
||||
em.persist(p);
|
||||
|
||||
em.flush();
|
||||
assertEquals("1 row must have been inserted",
|
||||
1, countRowsInTable("person"));
|
||||
}
|
||||
|
||||
public void testStateClean() {
|
||||
assertEquals("Should be no people from previous transactions",
|
||||
0, countRowsInTable("person"));
|
||||
}
|
||||
|
||||
public void testReuseInNewTransaction() {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
em.joinTransaction();
|
||||
|
||||
doInstantiateAndSave(em);
|
||||
endTransaction();
|
||||
|
||||
assertFalse(em.getTransaction().isActive());
|
||||
|
||||
startNewTransaction();
|
||||
// Call any method: should cause automatic tx invocation
|
||||
assertFalse(em.contains(new Person()));
|
||||
|
||||
assertFalse(em.getTransaction().isActive());
|
||||
em.joinTransaction();
|
||||
|
||||
assertTrue(em.getTransaction().isActive());
|
||||
|
||||
doInstantiateAndSave(em);
|
||||
setComplete();
|
||||
endTransaction(); // Should rollback
|
||||
assertEquals("Tx must have committed back",
|
||||
1, countRowsInTable("person"));
|
||||
|
||||
// Now clean up the database
|
||||
startNewTransaction();
|
||||
em.joinTransaction();
|
||||
deleteAllPeopleUsingEntityManager(em);
|
||||
assertEquals("People have been killed",
|
||||
0, countRowsInTable("person"));
|
||||
setComplete();
|
||||
}
|
||||
|
||||
public static void deleteAllPeopleUsingEntityManager(EntityManager em) {
|
||||
em.createQuery("delete from Person p").executeUpdate();
|
||||
}
|
||||
|
||||
public void testRollbackOccurs() {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
em.joinTransaction();
|
||||
doInstantiateAndSave(em);
|
||||
endTransaction(); // Should rollback
|
||||
assertEquals("Tx must have been rolled back",
|
||||
0, countRowsInTable("person"));
|
||||
}
|
||||
|
||||
public void testCommitOccurs() {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
em.joinTransaction();
|
||||
doInstantiateAndSave(em);
|
||||
|
||||
setComplete();
|
||||
endTransaction(); // Should rollback
|
||||
assertEquals("Tx must have committed back",
|
||||
1, countRowsInTable("person"));
|
||||
|
||||
// Now clean up the database
|
||||
deleteFromTables(new String[] { "person" });
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa;
|
||||
|
||||
import java.util.List;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.TransactionRequiredException;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.orm.jpa.domain.Person;
|
||||
import org.springframework.test.annotation.ExpectedException;
|
||||
import org.springframework.test.annotation.NotTransactional;
|
||||
|
||||
/**
|
||||
* Integration tests using in-memory database for container-managed JPA
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ContainerManagedEntityManagerIntegrationTests extends AbstractEntityManagerFactoryIntegrationTests {
|
||||
|
||||
@NotTransactional
|
||||
public void testExceptionTranslationWithDialectFoundOnIntroducedEntityManagerInfo() throws Exception {
|
||||
doTestExceptionTranslationWithDialectFound(((EntityManagerFactoryInfo) entityManagerFactory).getJpaDialect());
|
||||
}
|
||||
|
||||
@NotTransactional
|
||||
public void testExceptionTranslationWithDialectFoundOnEntityManagerFactoryBean() throws Exception {
|
||||
AbstractEntityManagerFactoryBean aefb =
|
||||
(AbstractEntityManagerFactoryBean) applicationContext.getBean("&entityManagerFactory");
|
||||
assertNotNull("Dialect must have been set", aefb.getJpaDialect());
|
||||
doTestExceptionTranslationWithDialectFound(aefb);
|
||||
}
|
||||
|
||||
protected void doTestExceptionTranslationWithDialectFound(PersistenceExceptionTranslator pet) throws Exception {
|
||||
RuntimeException in1 = new RuntimeException("in1");
|
||||
PersistenceException in2 = new PersistenceException();
|
||||
assertNull("No translation here", pet.translateExceptionIfPossible(in1));
|
||||
DataAccessException dex = pet.translateExceptionIfPossible(in2);
|
||||
assertNotNull(dex);
|
||||
assertSame(in2, dex.getCause());
|
||||
}
|
||||
|
||||
public void testEntityManagerProxyIsProxy() {
|
||||
EntityManager em = createContainerManagedEntityManager();
|
||||
assertTrue(Proxy.isProxyClass(em.getClass()));
|
||||
Query q = em.createQuery("select p from Person as p");
|
||||
List<Person> people = q.getResultList();
|
||||
assertTrue(people.isEmpty());
|
||||
|
||||
assertTrue("Should be open to start with", em.isOpen());
|
||||
try {
|
||||
em.close();
|
||||
fail("Close should not work on container managed EM");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
// Ok
|
||||
}
|
||||
assertTrue(em.isOpen());
|
||||
}
|
||||
|
||||
// This would be legal, at least if not actually _starting_ a tx
|
||||
@ExpectedException(IllegalStateException.class)
|
||||
public void testEntityManagerProxyRejectsProgrammaticTxManagement() {
|
||||
createContainerManagedEntityManager().getTransaction();
|
||||
}
|
||||
|
||||
/*
|
||||
* See comments in spec on EntityManager.joinTransaction().
|
||||
* We take the view that this is a valid no op.
|
||||
*/
|
||||
public void testContainerEntityManagerProxyAllowsJoinTransactionInTransaction() {
|
||||
createContainerManagedEntityManager().joinTransaction();
|
||||
}
|
||||
|
||||
@NotTransactional
|
||||
@ExpectedException(TransactionRequiredException.class)
|
||||
public void testContainerEntityManagerProxyRejectsJoinTransactionWithoutTransaction() {
|
||||
createContainerManagedEntityManager().joinTransaction();
|
||||
}
|
||||
|
||||
public void testInstantiateAndSave() {
|
||||
EntityManager em = createContainerManagedEntityManager();
|
||||
doInstantiateAndSave(em);
|
||||
}
|
||||
|
||||
public void doInstantiateAndSave(EntityManager em) {
|
||||
assertEquals("Should be no people from previous transactions",
|
||||
0, countRowsInTable("person"));
|
||||
Person p = new Person();
|
||||
|
||||
p.setFirstName("Tony");
|
||||
p.setLastName("Blair");
|
||||
em.persist(p);
|
||||
|
||||
em.flush();
|
||||
assertEquals("1 row must have been inserted",
|
||||
1, countRowsInTable("person"));
|
||||
}
|
||||
|
||||
public void testReuseInNewTransaction() {
|
||||
EntityManager em = createContainerManagedEntityManager();
|
||||
doInstantiateAndSave(em);
|
||||
endTransaction();
|
||||
|
||||
//assertFalse(em.getTransaction().isActive());
|
||||
|
||||
startNewTransaction();
|
||||
// Call any method: should cause automatic tx invocation
|
||||
assertFalse(em.contains(new Person()));
|
||||
//assertTrue(em.getTransaction().isActive());
|
||||
|
||||
doInstantiateAndSave(em);
|
||||
setComplete();
|
||||
endTransaction(); // Should rollback
|
||||
assertEquals("Tx must have committed back",
|
||||
1, countRowsInTable("person"));
|
||||
|
||||
// Now clean up the database
|
||||
deleteFromTables(new String[] { "person" });
|
||||
}
|
||||
|
||||
public void testRollbackOccurs() {
|
||||
EntityManager em = createContainerManagedEntityManager();
|
||||
doInstantiateAndSave(em);
|
||||
endTransaction(); // Should rollback
|
||||
assertEquals("Tx must have been rolled back",
|
||||
0, countRowsInTable("person"));
|
||||
}
|
||||
|
||||
public void testCommitOccurs() {
|
||||
EntityManager em = createContainerManagedEntityManager();
|
||||
doInstantiateAndSave(em);
|
||||
setComplete();
|
||||
endTransaction(); // Should rollback
|
||||
assertEquals("Tx must have committed back",
|
||||
1, countRowsInTable("person"));
|
||||
|
||||
// Now clean up the database
|
||||
deleteFromTables(new String[] { "person" });
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: This displays incorrect behavior in TopLink because of its EJBQLException -
|
||||
* which is not a subclass of PersistenceException but rather of TopLinkException!
|
||||
public void testEntityManagerProxyException() {
|
||||
EntityManager em = entityManagerFactory.createEntityManager();
|
||||
try {
|
||||
em.createQuery("select p from Person p where p.o=0").getResultList();
|
||||
fail("Semantic nonsense should be rejected");
|
||||
}
|
||||
catch (PersistenceException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Costin Leau
|
||||
*
|
||||
*/
|
||||
public class DefaultJpaDialectTests extends TestCase {
|
||||
JpaDialect dialect;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
dialect = new DefaultJpaDialect();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
dialect = null;
|
||||
}
|
||||
|
||||
public void testDefaultTransactionDefinition() throws Exception {
|
||||
DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
|
||||
definition.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
|
||||
|
||||
try {
|
||||
dialect.beginTransaction(null, definition);
|
||||
fail("expected exception");
|
||||
}
|
||||
catch (TransactionException e) {
|
||||
// ok
|
||||
}
|
||||
}
|
||||
|
||||
public void testDefaultBeginTransaction() throws Exception {
|
||||
TransactionDefinition definition = new DefaultTransactionDefinition();
|
||||
MockControl entityControl = MockControl.createControl(EntityManager.class);
|
||||
EntityManager entityManager = (EntityManager) entityControl.getMock();
|
||||
|
||||
MockControl txControl = MockControl.createControl(EntityTransaction.class);
|
||||
EntityTransaction entityTx = (EntityTransaction) txControl.getMock();
|
||||
|
||||
entityControl.expectAndReturn(entityManager.getTransaction(), entityTx);
|
||||
entityTx.begin();
|
||||
|
||||
entityControl.replay();
|
||||
txControl.replay();
|
||||
|
||||
dialect.beginTransaction(entityManager, definition);
|
||||
|
||||
entityControl.verify();
|
||||
txControl.verify();
|
||||
}
|
||||
|
||||
public void testTranslateException() {
|
||||
OptimisticLockException ex = new OptimisticLockException();
|
||||
assertEquals(
|
||||
EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(ex).getCause(),
|
||||
dialect.translateExceptionIfPossible(ex).getCause());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
public class EntityManagerFactoryBeanSupportTests extends AbstractEntityManagerFactoryBeanTests {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mockEmf.close();
|
||||
emfMc.setVoidCallable();
|
||||
emfMc.replay();
|
||||
}
|
||||
|
||||
public void testHookIsCalled() throws Exception {
|
||||
DummyEntityManagerFactoryBean demf = new DummyEntityManagerFactoryBean(mockEmf);
|
||||
|
||||
demf.afterPropertiesSet();
|
||||
|
||||
checkInvariants(demf);
|
||||
|
||||
// Should trigger close method expected by EntityManagerFactory mock
|
||||
demf.destroy();
|
||||
|
||||
emfMc.verify();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa;
|
||||
|
||||
import javax.persistence.EntityExistsException;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.TransactionRequiredException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.easymock.MockControl;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class EntityManagerFactoryUtilsTests extends TestCase {
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.orm.jpa.EntityManagerFactoryUtils.doGetEntityManager(EntityManagerFactory)'
|
||||
*/
|
||||
public void testDoGetEntityManager() {
|
||||
// test null assertion
|
||||
try {
|
||||
EntityManagerFactoryUtils.doGetTransactionalEntityManager(null, null);
|
||||
fail("expected exception");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// it's okay
|
||||
}
|
||||
MockControl mockControl = MockControl.createControl(EntityManagerFactory.class);
|
||||
EntityManagerFactory factory = (EntityManagerFactory) mockControl.getMock();
|
||||
|
||||
mockControl.replay();
|
||||
// no tx active
|
||||
assertNull(EntityManagerFactoryUtils.doGetTransactionalEntityManager(factory, null));
|
||||
mockControl.verify();
|
||||
|
||||
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
|
||||
}
|
||||
|
||||
public void testDoGetEntityManagerWithTx() throws Exception {
|
||||
try {
|
||||
MockControl mockControl = MockControl.createControl(EntityManagerFactory.class);
|
||||
EntityManagerFactory factory = (EntityManagerFactory) mockControl.getMock();
|
||||
|
||||
MockControl managerControl = MockControl.createControl(EntityManager.class);
|
||||
EntityManager manager = (EntityManager) managerControl.getMock();
|
||||
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
mockControl.expectAndReturn(factory.createEntityManager(), manager);
|
||||
|
||||
mockControl.replay();
|
||||
// no tx active
|
||||
assertSame(manager, EntityManagerFactoryUtils.doGetTransactionalEntityManager(factory, null));
|
||||
assertSame(manager, ((EntityManagerHolder)TransactionSynchronizationManager.unbindResource(factory)).getEntityManager());
|
||||
|
||||
mockControl.verify();
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
|
||||
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
|
||||
}
|
||||
|
||||
public void testTranslatesIllegalStateException() {
|
||||
IllegalStateException ise = new IllegalStateException();
|
||||
DataAccessException dex = EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(ise);
|
||||
assertSame(ise, dex.getCause());
|
||||
assertTrue(dex instanceof InvalidDataAccessApiUsageException);
|
||||
}
|
||||
|
||||
public void testTranslatesIllegalArgumentException() {
|
||||
IllegalArgumentException iae = new IllegalArgumentException();
|
||||
DataAccessException dex = EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(iae);
|
||||
assertSame(iae, dex.getCause());
|
||||
assertTrue(dex instanceof InvalidDataAccessApiUsageException);
|
||||
}
|
||||
|
||||
/**
|
||||
* We do not convert unknown exceptions. They may result from user code.
|
||||
*/
|
||||
public void testDoesNotTranslateUnfamiliarException() {
|
||||
UnsupportedOperationException userRuntimeException = new UnsupportedOperationException();
|
||||
assertNull(
|
||||
"Exception should not be wrapped",
|
||||
EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(userRuntimeException));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessException(PersistenceException)'
|
||||
*/
|
||||
public void testConvertJpaPersistenceException() {
|
||||
EntityNotFoundException entityNotFound = new EntityNotFoundException();
|
||||
assertSame(JpaObjectRetrievalFailureException.class,
|
||||
EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(entityNotFound).getClass());
|
||||
|
||||
NoResultException noResult = new NoResultException();
|
||||
assertSame(EmptyResultDataAccessException.class,
|
||||
EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(noResult).getClass());
|
||||
|
||||
NonUniqueResultException nonUniqueResult = new NonUniqueResultException();
|
||||
assertSame(IncorrectResultSizeDataAccessException.class,
|
||||
EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(nonUniqueResult).getClass());
|
||||
|
||||
OptimisticLockException optimisticLock = new OptimisticLockException();
|
||||
assertSame(JpaOptimisticLockingFailureException.class,
|
||||
EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(optimisticLock).getClass());
|
||||
|
||||
EntityExistsException entityExists = new EntityExistsException("foo");
|
||||
assertSame(DataIntegrityViolationException.class,
|
||||
EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(entityExists).getClass());
|
||||
|
||||
TransactionRequiredException transactionRequired = new TransactionRequiredException("foo");
|
||||
assertSame(InvalidDataAccessApiUsageException.class,
|
||||
EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(transactionRequired).getClass());
|
||||
|
||||
PersistenceException unknown = new PersistenceException() {
|
||||
};
|
||||
assertSame(JpaSystemException.class,
|
||||
EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(unknown).getClass());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.aopalliance.intercept.Interceptor;
|
||||
import org.aopalliance.intercept.Invocation;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.easymock.MockControl;
|
||||
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class JpaInterceptorTests extends TestCase {
|
||||
|
||||
private MockControl factoryControl, managerControl;
|
||||
|
||||
private EntityManagerFactory factory;
|
||||
|
||||
private EntityManager entityManager;
|
||||
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
factoryControl = MockControl.createControl(EntityManagerFactory.class);
|
||||
factory = (EntityManagerFactory) factoryControl.getMock();
|
||||
managerControl = MockControl.createControl(EntityManager.class);
|
||||
entityManager = (EntityManager) managerControl.getMock();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
|
||||
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
|
||||
|
||||
factoryControl = null;
|
||||
factory = null;
|
||||
managerControl = null;
|
||||
entityManager = null;
|
||||
|
||||
}
|
||||
|
||||
public void testInterceptorWithNewEntityManager() throws PersistenceException {
|
||||
factoryControl.expectAndReturn(factory.createEntityManager(), entityManager);
|
||||
entityManager.close();
|
||||
|
||||
factoryControl.replay();
|
||||
managerControl.replay();
|
||||
|
||||
JpaInterceptor interceptor = new JpaInterceptor();
|
||||
interceptor.setEntityManagerFactory(factory);
|
||||
try {
|
||||
interceptor.invoke(new TestInvocation(factory));
|
||||
}
|
||||
catch (Throwable t) {
|
||||
fail("Should not have thrown Throwable: " + t.getMessage());
|
||||
}
|
||||
|
||||
factoryControl.verify();
|
||||
managerControl.verify();
|
||||
}
|
||||
|
||||
public void testInterceptorWithNewEntityManagerAndLazyFlush() throws PersistenceException {
|
||||
factoryControl.expectAndReturn(factory.createEntityManager(), entityManager);
|
||||
entityManager.close();
|
||||
|
||||
factoryControl.replay();
|
||||
managerControl.replay();
|
||||
|
||||
JpaInterceptor interceptor = new JpaInterceptor();
|
||||
interceptor.setFlushEager(false);
|
||||
interceptor.setEntityManagerFactory(factory);
|
||||
try {
|
||||
interceptor.invoke(new TestInvocation(factory));
|
||||
}
|
||||
catch (Throwable t) {
|
||||
fail("Should not have thrown Throwable: " + t.getMessage());
|
||||
}
|
||||
|
||||
factoryControl.verify();
|
||||
managerControl.verify();
|
||||
}
|
||||
|
||||
public void testInterceptorWithThreadBound() {
|
||||
factoryControl.replay();
|
||||
managerControl.replay();
|
||||
|
||||
TransactionSynchronizationManager.bindResource(factory, new EntityManagerHolder(entityManager));
|
||||
JpaInterceptor interceptor = new JpaInterceptor();
|
||||
interceptor.setEntityManagerFactory(factory);
|
||||
try {
|
||||
interceptor.invoke(new TestInvocation(factory));
|
||||
}
|
||||
catch (Throwable t) {
|
||||
fail("Should not have thrown Throwable: " + t.getMessage());
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.unbindResource(factory);
|
||||
}
|
||||
|
||||
factoryControl.verify();
|
||||
managerControl.verify();
|
||||
}
|
||||
|
||||
public void testInterceptorWithThreadBoundAndFlushEager() throws PersistenceException {
|
||||
//entityManager.setFlushMode(FlushModeType.AUTO);
|
||||
entityManager.flush();
|
||||
|
||||
factoryControl.replay();
|
||||
managerControl.replay();
|
||||
|
||||
TransactionSynchronizationManager.bindResource(factory, new EntityManagerHolder(entityManager));
|
||||
JpaInterceptor interceptor = new JpaInterceptor();
|
||||
interceptor.setFlushEager(true);
|
||||
interceptor.setEntityManagerFactory(factory);
|
||||
try {
|
||||
interceptor.invoke(new TestInvocation(factory));
|
||||
}
|
||||
catch (Throwable t) {
|
||||
fail("Should not have thrown Throwable: " + t.getMessage());
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.unbindResource(factory);
|
||||
}
|
||||
|
||||
factoryControl.verify();
|
||||
managerControl.verify();
|
||||
}
|
||||
|
||||
public void testInterceptorWithThreadBoundAndFlushCommit() {
|
||||
//entityManager.setFlushMode(FlushModeType.COMMIT);
|
||||
//entityManager.flush();
|
||||
|
||||
factoryControl.replay();
|
||||
managerControl.replay();
|
||||
|
||||
TransactionSynchronizationManager.bindResource(factory, new EntityManagerHolder(entityManager));
|
||||
JpaInterceptor interceptor = new JpaInterceptor();
|
||||
interceptor.setFlushEager(false);
|
||||
interceptor.setEntityManagerFactory(factory);
|
||||
try {
|
||||
interceptor.invoke(new TestInvocation(factory));
|
||||
}
|
||||
catch (Throwable t) {
|
||||
fail("Should not have thrown Throwable: " + t.getMessage());
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.unbindResource(factory);
|
||||
}
|
||||
|
||||
factoryControl.verify();
|
||||
managerControl.verify();
|
||||
}
|
||||
|
||||
public void testInterceptorWithFlushFailure() throws Throwable {
|
||||
factoryControl.expectAndReturn(factory.createEntityManager(), entityManager);
|
||||
entityManager.flush();
|
||||
|
||||
PersistenceException exception = new PersistenceException();
|
||||
managerControl.setThrowable(exception, 1);
|
||||
entityManager.close();
|
||||
|
||||
factoryControl.replay();
|
||||
managerControl.replay();
|
||||
|
||||
JpaInterceptor interceptor = new JpaInterceptor();
|
||||
interceptor.setFlushEager(true);
|
||||
interceptor.setEntityManagerFactory(factory);
|
||||
try {
|
||||
interceptor.invoke(new TestInvocation(factory));
|
||||
//fail("Should have thrown JpaSystemException");
|
||||
}
|
||||
catch (JpaSystemException ex) {
|
||||
// expected
|
||||
assertEquals(exception, ex.getCause());
|
||||
}
|
||||
|
||||
factoryControl.verify();
|
||||
managerControl.verify();
|
||||
}
|
||||
|
||||
public void testInterceptorWithFlushFailureWithoutConversion() throws Throwable {
|
||||
factoryControl.expectAndReturn(factory.createEntityManager(), entityManager);
|
||||
entityManager.flush();
|
||||
|
||||
PersistenceException exception = new PersistenceException();
|
||||
managerControl.setThrowable(exception, 1);
|
||||
entityManager.close();
|
||||
|
||||
factoryControl.replay();
|
||||
managerControl.replay();
|
||||
|
||||
JpaInterceptor interceptor = new JpaInterceptor();
|
||||
interceptor.setFlushEager(true);
|
||||
interceptor.setExceptionConversionEnabled(false);
|
||||
interceptor.setEntityManagerFactory(factory);
|
||||
try {
|
||||
interceptor.invoke(new TestInvocation(factory));
|
||||
//fail("Should have thrown JpaSystemException");
|
||||
}
|
||||
catch (PersistenceException ex) {
|
||||
// expected
|
||||
assertEquals(exception, ex);
|
||||
}
|
||||
|
||||
factoryControl.verify();
|
||||
managerControl.verify();
|
||||
}
|
||||
|
||||
|
||||
private static class TestInvocation implements MethodInvocation {
|
||||
|
||||
private EntityManagerFactory entityManagerFactory;
|
||||
|
||||
public TestInvocation(EntityManagerFactory entityManagerFactory) {
|
||||
this.entityManagerFactory = entityManagerFactory;
|
||||
}
|
||||
|
||||
public Object proceed() throws Throwable {
|
||||
if (!TransactionSynchronizationManager.hasResource(this.entityManagerFactory)) {
|
||||
throw new IllegalStateException("Session not bound");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getCurrentInterceptorIndex() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getNumberOfInterceptors() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Interceptor getInterceptor(int i) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public AccessibleObject getStaticPart() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getArgument(int i) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object[] getArguments() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setArgument(int i, Object handler) {
|
||||
}
|
||||
|
||||
public int getArgumentCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Object getThis() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getProxy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Invocation cloneInstance() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,521 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.easymock.MockControl;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class JpaTemplateTests extends TestCase {
|
||||
|
||||
private JpaTemplate template;
|
||||
|
||||
private MockControl factoryControl, managerControl;
|
||||
|
||||
private EntityManager manager;
|
||||
|
||||
private EntityManagerFactory factory;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
template = new JpaTemplate();
|
||||
|
||||
factoryControl = MockControl.createControl(EntityManagerFactory.class);
|
||||
factory = (EntityManagerFactory) factoryControl.getMock();
|
||||
managerControl = MockControl.createControl(EntityManager.class);
|
||||
manager = (EntityManager) managerControl.getMock();
|
||||
|
||||
template.setEntityManager(manager);
|
||||
template.afterPropertiesSet();
|
||||
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
template = null;
|
||||
factoryControl = null;
|
||||
managerControl = null;
|
||||
manager = null;
|
||||
factory = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.orm.jpa.JpaTemplate.JpaTemplate(EntityManagerFactory)'
|
||||
*/
|
||||
public void testJpaTemplateEntityManagerFactory() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.orm.jpa.JpaTemplate.JpaTemplate(EntityManager)'
|
||||
*/
|
||||
public void testJpaTemplateEntityManager() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.orm.jpa.JpaTemplate.execute(JpaCallback)'
|
||||
*/
|
||||
public void testExecuteJpaCallback() {
|
||||
template.setExposeNativeEntityManager(true);
|
||||
template.setEntityManager(manager);
|
||||
template.afterPropertiesSet();
|
||||
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
|
||||
template.execute(new JpaCallback() {
|
||||
|
||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
||||
assertSame(em, manager);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
template.setExposeNativeEntityManager(false);
|
||||
template.execute(new JpaCallback() {
|
||||
|
||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
||||
assertNotSame(em, manager);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.orm.jpa.JpaTemplate.executeFind(JpaCallback)'
|
||||
*/
|
||||
public void testExecuteFind() {
|
||||
template.setEntityManager(manager);
|
||||
template.setExposeNativeEntityManager(true);
|
||||
template.afterPropertiesSet();
|
||||
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
|
||||
try {
|
||||
template.executeFind(new JpaCallback() {
|
||||
|
||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
||||
assertSame(em, manager);
|
||||
return new Object();
|
||||
}
|
||||
});
|
||||
fail("should have thrown exception");
|
||||
}
|
||||
catch (DataAccessException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.orm.jpa.JpaTemplate.execute(JpaCallback, boolean)'
|
||||
*/
|
||||
public void testExecuteJpaCallbackBoolean() {
|
||||
template = new JpaTemplate();
|
||||
template.setExposeNativeEntityManager(false);
|
||||
template.setEntityManagerFactory(factory);
|
||||
template.afterPropertiesSet();
|
||||
|
||||
factoryControl.expectAndReturn(factory.createEntityManager(), manager);
|
||||
manager.close();
|
||||
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
|
||||
template.execute(new JpaCallback() {
|
||||
|
||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
||||
assertSame(em, manager);
|
||||
return null;
|
||||
}
|
||||
}, true);
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
|
||||
public void testExecuteJpaCallbackBooleanWithPrebound() {
|
||||
template.setExposeNativeEntityManager(false);
|
||||
template.setEntityManagerFactory(factory);
|
||||
template.afterPropertiesSet();
|
||||
|
||||
TransactionSynchronizationManager.bindResource(factory, new EntityManagerHolder(manager));
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
|
||||
try {
|
||||
template.execute(new JpaCallback() {
|
||||
|
||||
public Object doInJpa(EntityManager em) throws PersistenceException {
|
||||
assertSame(em, manager);
|
||||
return null;
|
||||
}
|
||||
}, true);
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.unbindResource(factory);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.orm.jpa.JpaTemplate.createSharedEntityManager(EntityManager)'
|
||||
*/
|
||||
public void testCreateEntityManagerProxy() {
|
||||
manager.clear();
|
||||
managerControl.replay();
|
||||
|
||||
EntityManager proxy = template.createEntityManagerProxy(manager);
|
||||
assertNotSame(manager, proxy);
|
||||
assertFalse(manager.equals(proxy));
|
||||
assertFalse(manager.hashCode() == proxy.hashCode());
|
||||
// close call not propagated to the em
|
||||
proxy.close();
|
||||
proxy.clear();
|
||||
|
||||
managerControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.find(Class<T>,
|
||||
* Object) <T>'
|
||||
*/
|
||||
public void testFindClassOfTObject() {
|
||||
Integer result = new Integer(1);
|
||||
Object id = new Object();
|
||||
managerControl.expectAndReturn(manager.find(Number.class, id), result);
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
|
||||
assertSame(result, template.find(Number.class, id));
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.orm.jpa.JpaTemplate.getReference(Class<T>, Object)
|
||||
* <T>'
|
||||
*/
|
||||
public void testGetReference() {
|
||||
Integer reference = new Integer(1);
|
||||
Object id = new Object();
|
||||
managerControl.expectAndReturn(manager.getReference(Number.class, id), reference);
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
|
||||
assertSame(reference, template.getReference(Number.class, id));
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.orm.jpa.JpaTemplate.contains(Object)'
|
||||
*/
|
||||
public void testContains() {
|
||||
boolean result = true;
|
||||
Object entity = new Object();
|
||||
managerControl.expectAndReturn(manager.contains(entity), result);
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
|
||||
assertSame(result, template.contains(entity));
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.refresh(Object)'
|
||||
*/
|
||||
public void testRefresh() {
|
||||
Object entity = new Object();
|
||||
manager.refresh(entity);
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
|
||||
template.refresh(entity);
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.persist(Object)'
|
||||
*/
|
||||
public void testPersist() {
|
||||
Object entity = new Object();
|
||||
manager.persist(entity);
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
|
||||
template.persist(entity);
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.merge(T) <T>'
|
||||
*/
|
||||
public void testMerge() {
|
||||
Object result = new Object();
|
||||
Object entity = new Object();
|
||||
managerControl.expectAndReturn(manager.merge(entity), result);
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
|
||||
assertSame(result, template.merge(entity));
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.remove(Object)'
|
||||
*/
|
||||
public void testRemove() {
|
||||
Object entity = new Object();
|
||||
manager.remove(entity);
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
|
||||
template.remove(entity);
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.flush()'
|
||||
*/
|
||||
public void testFlush() {
|
||||
manager.flush();
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
|
||||
template.flush();
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.find(String)'
|
||||
*/
|
||||
public void testFindString() {
|
||||
String queryString = "some query";
|
||||
MockControl queryControl = MockControl.createControl(Query.class);
|
||||
Query query = (Query) queryControl.getMock();
|
||||
List result = new ArrayList();
|
||||
|
||||
managerControl.expectAndReturn(manager.createQuery(queryString), query);
|
||||
queryControl.expectAndReturn(query.getResultList(), result);
|
||||
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
queryControl.replay();
|
||||
|
||||
assertSame(result, template.find(queryString));
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
queryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.find(String,
|
||||
* Object...)'
|
||||
*/
|
||||
public void testFindStringObjectArray() {
|
||||
String queryString = "some query";
|
||||
MockControl queryControl = MockControl.createControl(Query.class);
|
||||
Query query = (Query) queryControl.getMock();
|
||||
List result = new ArrayList();
|
||||
Object param1 = new Object();
|
||||
Object param2 = new Object();
|
||||
Object[] params = new Object[] { param1, param2 };
|
||||
|
||||
managerControl.expectAndReturn(manager.createQuery(queryString), query);
|
||||
queryControl.expectAndReturn(query.setParameter(1, param1), null);
|
||||
queryControl.expectAndReturn(query.setParameter(2, param2), null);
|
||||
|
||||
queryControl.expectAndReturn(query.getResultList(), result);
|
||||
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
queryControl.replay();
|
||||
|
||||
assertSame(result, template.find(queryString, params));
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
queryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.springframework.orm.jpa.JpaTemplate.find(String, Map<String,
|
||||
* Object>)'
|
||||
*/
|
||||
public void testFindStringMapOfStringObject() {
|
||||
String queryString = "some query";
|
||||
MockControl queryControl = MockControl.createControl(Query.class);
|
||||
Query query = (Query) queryControl.getMock();
|
||||
List result = new ArrayList();
|
||||
Object param1 = new Object();
|
||||
Object param2 = new Object();
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("param1", param1);
|
||||
params.put("param2", param2);
|
||||
|
||||
managerControl.expectAndReturn(manager.createQuery(queryString), query);
|
||||
queryControl.expectAndReturn(query.setParameter("param1", param1), null);
|
||||
queryControl.expectAndReturn(query.setParameter("param2", param2), null);
|
||||
|
||||
queryControl.expectAndReturn(query.getResultList(), result);
|
||||
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
queryControl.replay();
|
||||
|
||||
assertSame(result, template.findByNamedParams(queryString, params));
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
queryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.orm.jpa.JpaTemplate.findByNamedQuery(String)'
|
||||
*/
|
||||
public void testFindByNamedQueryString() {
|
||||
String queryName = "some query name";
|
||||
MockControl queryControl = MockControl.createControl(Query.class);
|
||||
Query query = (Query) queryControl.getMock();
|
||||
List result = new ArrayList();
|
||||
|
||||
managerControl.expectAndReturn(manager.createNamedQuery(queryName), query);
|
||||
|
||||
queryControl.expectAndReturn(query.getResultList(), result);
|
||||
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
queryControl.replay();
|
||||
|
||||
assertSame(result, template.findByNamedQuery(queryName));
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
queryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.orm.jpa.JpaTemplate.findByNamedQuery(String,
|
||||
* Object...)'
|
||||
*/
|
||||
public void testFindByNamedQueryStringObjectArray() {
|
||||
String queryName = "some query name";
|
||||
MockControl queryControl = MockControl.createControl(Query.class);
|
||||
Query query = (Query) queryControl.getMock();
|
||||
List result = new ArrayList();
|
||||
Object param1 = new Object();
|
||||
Object param2 = new Object();
|
||||
Object[] params = new Object[] { param1, param2 };
|
||||
|
||||
managerControl.expectAndReturn(manager.createNamedQuery(queryName), query);
|
||||
queryControl.expectAndReturn(query.setParameter(1, param1), null);
|
||||
queryControl.expectAndReturn(query.setParameter(2, param2), null);
|
||||
|
||||
queryControl.expectAndReturn(query.getResultList(), result);
|
||||
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
queryControl.replay();
|
||||
|
||||
assertSame(result, template.findByNamedQuery(queryName, params));
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
queryControl.verify();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.springframework.orm.jpa.JpaTemplate.findByNamedQuery(String, Map<String,
|
||||
* Object>)'
|
||||
*/
|
||||
public void testFindByNamedQueryStringMapOfStringObject() {
|
||||
String queryName = "some query name";
|
||||
MockControl queryControl = MockControl.createControl(Query.class);
|
||||
Query query = (Query) queryControl.getMock();
|
||||
List result = new ArrayList();
|
||||
Object param1 = new Object();
|
||||
Object param2 = new Object();
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("param1", param1);
|
||||
params.put("param2", param2);
|
||||
|
||||
managerControl.expectAndReturn(manager.createNamedQuery(queryName), query);
|
||||
queryControl.expectAndReturn(query.setParameter("param1", param1), null);
|
||||
queryControl.expectAndReturn(query.setParameter("param2", param2), null);
|
||||
|
||||
queryControl.expectAndReturn(query.getResultList(), result);
|
||||
|
||||
managerControl.replay();
|
||||
factoryControl.replay();
|
||||
queryControl.replay();
|
||||
|
||||
assertSame(result, template.findByNamedQueryAndNamedParams(queryName, params));
|
||||
|
||||
managerControl.verify();
|
||||
factoryControl.verify();
|
||||
queryControl.verify();
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,397 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.spi.PersistenceProvider;
|
||||
import javax.persistence.spi.PersistenceUnitInfo;
|
||||
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver;
|
||||
import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class LocalContainerEntityManagerFactoryBeanTests extends AbstractEntityManagerFactoryBeanTests {
|
||||
|
||||
// Static fields set by inner class DummyPersistenceProvider
|
||||
|
||||
private static Map actualProps;
|
||||
|
||||
private static PersistenceUnitInfo actualPui;
|
||||
|
||||
|
||||
public void testValidPersistenceUnit() throws Exception {
|
||||
parseValidPersistenceUnit();
|
||||
}
|
||||
|
||||
public void testExceptionTranslationWithNoDialect() throws Exception {
|
||||
LocalContainerEntityManagerFactoryBean cefb = parseValidPersistenceUnit();
|
||||
EntityManagerFactory emf = cefb.getObject();
|
||||
assertNull("No dialect set", cefb.getJpaDialect());
|
||||
|
||||
RuntimeException in1 = new RuntimeException("in1");
|
||||
PersistenceException in2 = new PersistenceException();
|
||||
assertNull("No translation here", cefb.translateExceptionIfPossible(in1));
|
||||
DataAccessException dex = cefb.translateExceptionIfPossible(in2);
|
||||
assertNotNull(dex);
|
||||
assertSame(in2, dex.getCause());
|
||||
}
|
||||
|
||||
public void testEntityManagerFactoryIsProxied() throws Exception {
|
||||
LocalContainerEntityManagerFactoryBean cefb = parseValidPersistenceUnit();
|
||||
EntityManagerFactory emf = cefb.getObject();
|
||||
assertSame("EntityManagerFactory reference must be cached after init", emf, cefb.getObject());
|
||||
|
||||
assertNotSame("EMF must be proxied", mockEmf, emf);
|
||||
assertTrue(emf.equals(emf));
|
||||
}
|
||||
|
||||
public void testApplicationManagedEntityManagerWithoutTransaction() throws Exception {
|
||||
Object testEntity = new Object();
|
||||
|
||||
MockControl emMc = MockControl.createControl(EntityManager.class);
|
||||
EntityManager mockEm = (EntityManager) emMc.getMock();
|
||||
mockEm.contains(testEntity);
|
||||
emMc.setReturnValue(false);
|
||||
emMc.replay();
|
||||
|
||||
// finish recording mock calls
|
||||
mockEmf.createEntityManager();
|
||||
emfMc.setReturnValue(mockEm);
|
||||
mockEmf.close();
|
||||
emfMc.setVoidCallable();
|
||||
emfMc.replay();
|
||||
|
||||
LocalContainerEntityManagerFactoryBean cefb = parseValidPersistenceUnit();
|
||||
EntityManagerFactory emf = cefb.getObject();
|
||||
assertSame("EntityManagerFactory reference must be cached after init", emf, cefb.getObject());
|
||||
|
||||
assertNotSame("EMF must be proxied", mockEmf, emf);
|
||||
EntityManager em = emf.createEntityManager();
|
||||
assertFalse(em.contains(testEntity));
|
||||
|
||||
cefb.destroy();
|
||||
|
||||
emfMc.verify();
|
||||
emMc.verify();
|
||||
}
|
||||
|
||||
public void testApplicationManagedEntityManagerWithTransaction() throws Exception {
|
||||
Object testEntity = new Object();
|
||||
|
||||
MockControl tmMc = MockControl.createControl(EntityTransaction.class);
|
||||
EntityTransaction mockTx = (EntityTransaction) tmMc.getMock();
|
||||
mockTx.isActive();
|
||||
tmMc.setReturnValue(false);
|
||||
mockTx.begin();
|
||||
tmMc.setVoidCallable();
|
||||
mockTx.commit();
|
||||
tmMc.setVoidCallable();
|
||||
tmMc.replay();
|
||||
|
||||
// This one's for the tx (shared)
|
||||
MockControl sharedEmMc = MockControl.createControl(EntityManager.class);
|
||||
EntityManager sharedEm = (EntityManager) sharedEmMc.getMock();
|
||||
sharedEm.getTransaction();
|
||||
sharedEmMc.setReturnValue(new NoOpEntityTransaction(), 3);
|
||||
sharedEm.close();
|
||||
sharedEmMc.setVoidCallable();
|
||||
sharedEmMc.replay();
|
||||
mockEmf.createEntityManager();
|
||||
emfMc.setReturnValue(sharedEm);
|
||||
|
||||
// This is the application-specific one
|
||||
MockControl emMc = MockControl.createControl(EntityManager.class);
|
||||
EntityManager mockEm = (EntityManager) emMc.getMock();
|
||||
mockEm.getTransaction();
|
||||
emMc.setReturnValue(mockTx, 3);
|
||||
mockEm.contains(testEntity);
|
||||
emMc.setReturnValue(false);
|
||||
emMc.replay();
|
||||
|
||||
mockEmf.createEntityManager();
|
||||
emfMc.setReturnValue(mockEm);
|
||||
mockEmf.close();
|
||||
emfMc.setVoidCallable();
|
||||
emfMc.replay();
|
||||
|
||||
LocalContainerEntityManagerFactoryBean cefb = parseValidPersistenceUnit();
|
||||
|
||||
JpaTransactionManager jpatm = new JpaTransactionManager();
|
||||
jpatm.setEntityManagerFactory(cefb.getObject());
|
||||
|
||||
TransactionStatus txStatus = jpatm.getTransaction(new DefaultTransactionAttribute());
|
||||
|
||||
EntityManagerFactory emf = cefb.getObject();
|
||||
assertSame("EntityManagerFactory reference must be cached after init", emf, cefb.getObject());
|
||||
|
||||
assertNotSame("EMF must be proxied", mockEmf, emf);
|
||||
EntityManager em = emf.createEntityManager();
|
||||
em.joinTransaction();
|
||||
assertFalse(em.contains(testEntity));
|
||||
|
||||
jpatm.commit(txStatus);
|
||||
|
||||
cefb.destroy();
|
||||
|
||||
emfMc.verify();
|
||||
emMc.verify();
|
||||
tmMc.verify();
|
||||
}
|
||||
|
||||
public void testApplicationManagedEntityManagerWithTransactionAndCommitException() throws Exception {
|
||||
Object testEntity = new Object();
|
||||
|
||||
MockControl tmMc = MockControl.createControl(EntityTransaction.class);
|
||||
EntityTransaction mockTx = (EntityTransaction) tmMc.getMock();
|
||||
mockTx.isActive();
|
||||
tmMc.setReturnValue(false);
|
||||
mockTx.begin();
|
||||
tmMc.setVoidCallable();
|
||||
mockTx.commit();
|
||||
tmMc.setThrowable(new OptimisticLockException());
|
||||
tmMc.replay();
|
||||
|
||||
// This one's for the tx (shared)
|
||||
MockControl sharedEmMc = MockControl.createControl(EntityManager.class);
|
||||
EntityManager sharedEm = (EntityManager) sharedEmMc.getMock();
|
||||
sharedEm.getTransaction();
|
||||
sharedEmMc.setReturnValue(new NoOpEntityTransaction(), 3);
|
||||
sharedEm.close();
|
||||
sharedEmMc.setVoidCallable();
|
||||
sharedEmMc.replay();
|
||||
mockEmf.createEntityManager();
|
||||
emfMc.setReturnValue(sharedEm);
|
||||
|
||||
// This is the application-specific one
|
||||
MockControl emMc = MockControl.createControl(EntityManager.class);
|
||||
EntityManager mockEm = (EntityManager) emMc.getMock();
|
||||
mockEm.getTransaction();
|
||||
emMc.setReturnValue(mockTx, 3);
|
||||
mockEm.contains(testEntity);
|
||||
emMc.setReturnValue(false);
|
||||
emMc.replay();
|
||||
|
||||
mockEmf.createEntityManager();
|
||||
emfMc.setReturnValue(mockEm);
|
||||
mockEmf.close();
|
||||
emfMc.setVoidCallable();
|
||||
emfMc.replay();
|
||||
|
||||
LocalContainerEntityManagerFactoryBean cefb = parseValidPersistenceUnit();
|
||||
|
||||
JpaTransactionManager jpatm = new JpaTransactionManager();
|
||||
jpatm.setEntityManagerFactory(cefb.getObject());
|
||||
|
||||
TransactionStatus txStatus = jpatm.getTransaction(new DefaultTransactionAttribute());
|
||||
|
||||
EntityManagerFactory emf = cefb.getObject();
|
||||
assertSame("EntityManagerFactory reference must be cached after init", emf, cefb.getObject());
|
||||
|
||||
assertNotSame("EMF must be proxied", mockEmf, emf);
|
||||
EntityManager em = emf.createEntityManager();
|
||||
em.joinTransaction();
|
||||
assertFalse(em.contains(testEntity));
|
||||
|
||||
try {
|
||||
jpatm.commit(txStatus);
|
||||
fail("Should have thrown OptimisticLockingFailureException");
|
||||
}
|
||||
catch (OptimisticLockingFailureException ex) {
|
||||
// expected
|
||||
}
|
||||
|
||||
cefb.destroy();
|
||||
|
||||
emfMc.verify();
|
||||
emMc.verify();
|
||||
tmMc.verify();
|
||||
}
|
||||
|
||||
public void testApplicationManagedEntityManagerWithJtaTransaction() throws Exception {
|
||||
Object testEntity = new Object();
|
||||
|
||||
// This one's for the tx (shared)
|
||||
MockControl sharedEmMc = MockControl.createControl(EntityManager.class);
|
||||
EntityManager sharedEm = (EntityManager) sharedEmMc.getMock();
|
||||
sharedEm.getTransaction();
|
||||
sharedEmMc.setReturnValue(new NoOpEntityTransaction(), 3);
|
||||
sharedEm.close();
|
||||
sharedEmMc.setVoidCallable(1);
|
||||
sharedEmMc.replay();
|
||||
mockEmf.createEntityManager();
|
||||
emfMc.setReturnValue(sharedEm);
|
||||
|
||||
// This is the application-specific one
|
||||
MockControl emMc = MockControl.createControl(EntityManager.class);
|
||||
EntityManager mockEm = (EntityManager) emMc.getMock();
|
||||
mockEm.joinTransaction();
|
||||
emMc.setVoidCallable(1);
|
||||
mockEm.contains(testEntity);
|
||||
emMc.setReturnValue(false);
|
||||
emMc.replay();
|
||||
|
||||
mockEmf.createEntityManager();
|
||||
emfMc.setReturnValue(mockEm);
|
||||
mockEmf.close();
|
||||
emfMc.setVoidCallable();
|
||||
emfMc.replay();
|
||||
|
||||
LocalContainerEntityManagerFactoryBean cefb = parseValidPersistenceUnit();
|
||||
MutablePersistenceUnitInfo pui = ((MutablePersistenceUnitInfo) cefb.getPersistenceUnitInfo());
|
||||
pui.setTransactionType(PersistenceUnitTransactionType.JTA);
|
||||
|
||||
JpaTransactionManager jpatm = new JpaTransactionManager();
|
||||
jpatm.setEntityManagerFactory(cefb.getObject());
|
||||
|
||||
TransactionStatus txStatus = jpatm.getTransaction(new DefaultTransactionAttribute());
|
||||
|
||||
EntityManagerFactory emf = cefb.getObject();
|
||||
assertSame("EntityManagerFactory reference must be cached after init", emf, cefb.getObject());
|
||||
|
||||
assertNotSame("EMF must be proxied", mockEmf, emf);
|
||||
EntityManager em = emf.createEntityManager();
|
||||
em.joinTransaction();
|
||||
assertFalse(em.contains(testEntity));
|
||||
|
||||
jpatm.commit(txStatus);
|
||||
|
||||
cefb.destroy();
|
||||
|
||||
emfMc.verify();
|
||||
emMc.verify();
|
||||
}
|
||||
|
||||
public LocalContainerEntityManagerFactoryBean parseValidPersistenceUnit() throws Exception {
|
||||
LocalContainerEntityManagerFactoryBean emfb = createEntityManagerFactoryBean(
|
||||
"org/springframework/orm/jpa/domain/persistence.xml", null,
|
||||
"Person");
|
||||
return emfb;
|
||||
}
|
||||
|
||||
public void testInvalidPersistenceUnitName() throws Exception {
|
||||
try {
|
||||
createEntityManagerFactoryBean("org/springframework/orm/jpa/domain/persistence.xml", null, "call me Bob");
|
||||
fail("Should not create factory with this name");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// Ok
|
||||
}
|
||||
}
|
||||
|
||||
protected LocalContainerEntityManagerFactoryBean createEntityManagerFactoryBean(
|
||||
String persistenceXml, Properties props, String entityManagerName) throws Exception {
|
||||
|
||||
// This will be set by DummyPersistenceProvider
|
||||
actualPui = null;
|
||||
actualProps = null;
|
||||
|
||||
LocalContainerEntityManagerFactoryBean containerEmfb = new LocalContainerEntityManagerFactoryBean();
|
||||
|
||||
containerEmfb.setPersistenceUnitName(entityManagerName);
|
||||
containerEmfb.setPersistenceProviderClass(DummyContainerPersistenceProvider.class);
|
||||
if (props != null) {
|
||||
containerEmfb.setJpaProperties(props);
|
||||
}
|
||||
containerEmfb.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
|
||||
containerEmfb.setPersistenceXmlLocation(persistenceXml);
|
||||
containerEmfb.afterPropertiesSet();
|
||||
|
||||
assertEquals(entityManagerName, actualPui.getPersistenceUnitName());
|
||||
if (props != null) {
|
||||
assertEquals(props, actualProps);
|
||||
}
|
||||
//checkInvariants(containerEmfb);
|
||||
|
||||
return containerEmfb;
|
||||
|
||||
//containerEmfb.destroy();
|
||||
//emfMc.verify();
|
||||
}
|
||||
|
||||
public void testRejectsMissingPersistenceUnitInfo() throws Exception {
|
||||
LocalContainerEntityManagerFactoryBean containerEmfb = new LocalContainerEntityManagerFactoryBean();
|
||||
String entityManagerName = "call me Bob";
|
||||
|
||||
containerEmfb.setPersistenceUnitName(entityManagerName);
|
||||
containerEmfb.setPersistenceProviderClass(DummyContainerPersistenceProvider.class);
|
||||
|
||||
try {
|
||||
containerEmfb.afterPropertiesSet();
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// Ok
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class DummyContainerPersistenceProvider implements PersistenceProvider {
|
||||
|
||||
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo pui, Map map) {
|
||||
actualPui = pui;
|
||||
actualProps = map;
|
||||
return mockEmf;
|
||||
}
|
||||
|
||||
public EntityManagerFactory createEntityManagerFactory(String emfName, Map properties) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class NoOpEntityTransaction implements EntityTransaction {
|
||||
|
||||
public void begin() {
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
}
|
||||
|
||||
public void rollback() {
|
||||
}
|
||||
|
||||
public void setRollbackOnly() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean getRollbackOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.spi.PersistenceProvider;
|
||||
import javax.persistence.spi.PersistenceUnitInfo;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
public class LocalEntityManagerFactoryBeanTests extends AbstractEntityManagerFactoryBeanTests {
|
||||
|
||||
// Static fields set by inner class DummyPersistenceProvider
|
||||
|
||||
private static String actualName;
|
||||
|
||||
private static Map actualProps;
|
||||
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mockEmf.close();
|
||||
emfMc.setVoidCallable();
|
||||
emfMc.replay();
|
||||
}
|
||||
|
||||
public void testValidUsageWithDefaultProperties() throws Exception {
|
||||
testValidUsage(null);
|
||||
}
|
||||
|
||||
public void testValidUsageWithExplicitProperties() throws Exception {
|
||||
testValidUsage(new Properties());
|
||||
}
|
||||
|
||||
protected void testValidUsage(Properties props) throws Exception {
|
||||
// This will be set by DummyPersistenceProvider
|
||||
actualName = null;
|
||||
actualProps = null;
|
||||
|
||||
LocalEntityManagerFactoryBean lemfb = new LocalEntityManagerFactoryBean();
|
||||
String entityManagerName = "call me Bob";
|
||||
|
||||
lemfb.setPersistenceUnitName(entityManagerName);
|
||||
lemfb.setPersistenceProviderClass(DummyPersistenceProvider.class);
|
||||
if (props != null) {
|
||||
lemfb.setJpaProperties(props);
|
||||
}
|
||||
lemfb.afterPropertiesSet();
|
||||
|
||||
assertSame(entityManagerName, actualName);
|
||||
if (props != null) {
|
||||
assertEquals(props, actualProps);
|
||||
}
|
||||
checkInvariants(lemfb);
|
||||
|
||||
lemfb.destroy();
|
||||
|
||||
emfMc.verify();
|
||||
}
|
||||
|
||||
|
||||
protected static class DummyPersistenceProvider implements PersistenceProvider {
|
||||
|
||||
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo pui, Map map) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public EntityManagerFactory createEntityManagerFactory(String emfName, Map properties) {
|
||||
actualName = emfName;
|
||||
actualProps = properties;
|
||||
return mockEmf;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
|
||||
|
||||
<persistence-unit name="OrderManagement"/>
|
||||
|
||||
</persistence>
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.domain;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.PersistenceContext;
|
||||
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.beans.factory.annotation.Configurable;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
@Entity
|
||||
@Configurable
|
||||
public class ContextualPerson {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
private transient TestBean testBean;
|
||||
|
||||
// Lazy relationship to force use of instrumentation in JPA implementation.
|
||||
// TopLink, at least, will not instrument classes unless absolutely necessary.
|
||||
@OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
|
||||
@JoinColumn(name="DRIVERS_LICENSE_ID")
|
||||
private DriversLicense driversLicense;
|
||||
|
||||
private String first_name;
|
||||
|
||||
@Basic(fetch=FetchType.LAZY)
|
||||
private String last_name;
|
||||
|
||||
@PersistenceContext
|
||||
public transient EntityManager entityManager;
|
||||
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setTestBean(TestBean testBean) {
|
||||
this.testBean = testBean;
|
||||
}
|
||||
|
||||
public TestBean getTestBean() {
|
||||
return testBean;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.first_name = firstName;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return this.first_name;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.last_name = lastName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return this.last_name;
|
||||
}
|
||||
|
||||
public void setDriversLicense(DriversLicense driversLicense) {
|
||||
this.driversLicense = driversLicense;
|
||||
}
|
||||
|
||||
public DriversLicense getDriversLicense() {
|
||||
return this.driversLicense;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + ":(" + hashCode() + ") id=" + id +
|
||||
"; firstName=" + first_name + "; lastName=" + last_name + "; testBean=" + testBean;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.domain;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name="DRIVERS_LICENSE")
|
||||
public class DriversLicense {
|
||||
|
||||
@Id
|
||||
private int id;
|
||||
|
||||
private String serial_number;
|
||||
|
||||
|
||||
protected DriversLicense() {
|
||||
}
|
||||
|
||||
public DriversLicense(String serialNumber) {
|
||||
this.serial_number = serialNumber;
|
||||
}
|
||||
|
||||
public String getSerialNumber() {
|
||||
return serial_number;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.domain;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.beans.factory.annotation.Configurable;
|
||||
|
||||
/**
|
||||
* Simple JavaBean domain object representing an person.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
@Entity
|
||||
@Configurable
|
||||
public class Person {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
private transient TestBean testBean;
|
||||
|
||||
// Lazy relationship to force use of instrumentation in JPA implementation.
|
||||
// TopLink, at least, will not instrument classes unless absolutely necessary.
|
||||
@OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
|
||||
@JoinColumn(name="DRIVERS_LICENSE_ID")
|
||||
private DriversLicense driversLicense;
|
||||
|
||||
private String first_name;
|
||||
|
||||
@Basic(fetch=FetchType.LAZY)
|
||||
private String last_name;
|
||||
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setTestBean(TestBean testBean) {
|
||||
this.testBean = testBean;
|
||||
}
|
||||
|
||||
public TestBean getTestBean() {
|
||||
return testBean;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.first_name = firstName;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return this.first_name;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.last_name = lastName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return this.last_name;
|
||||
}
|
||||
|
||||
public void setDriversLicense(DriversLicense driversLicense) {
|
||||
this.driversLicense = driversLicense;
|
||||
}
|
||||
|
||||
public DriversLicense getDriversLicense() {
|
||||
return this.driversLicense;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + ":(" + hashCode() + ") id=" + id +
|
||||
"; firstName=" + first_name + "; lastName=" + last_name + "; testBean=" + testBean;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit name="Person" transaction-type="RESOURCE_LOCAL">
|
||||
<class>org.springframework.orm.jpa.domain.ContextualPerson</class>
|
||||
<class>org.springframework.orm.jpa.domain.DriversLicense</class>
|
||||
<class>org.springframework.orm.jpa.domain.Person</class>
|
||||
<exclude-unlisted-classes/>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
@@ -0,0 +1,17 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit name="Drivers" transaction-type="RESOURCE_LOCAL">
|
||||
<class>org.springframework.orm.jpa.domain.Person</class>
|
||||
<class>org.springframework.orm.jpa.domain.DriversLicense</class>
|
||||
<exclude-unlisted-classes/>
|
||||
</persistence-unit>
|
||||
|
||||
<persistence-unit name="Test" transaction-type="RESOURCE_LOCAL">
|
||||
<class>org.springframework.beans.TestBean</class>
|
||||
<exclude-unlisted-classes/>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
@@ -0,0 +1,12 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit name="Person" transaction-type="RESOURCE_LOCAL">
|
||||
<class>org.springframework.orm.jpa.domain.Person</class>
|
||||
<class>org.springframework.orm.jpa.domain.DriversLicense</class>
|
||||
<exclude-unlisted-classes/>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.eclipselink;
|
||||
|
||||
import org.eclipse.persistence.jpa.JpaEntityManager;
|
||||
|
||||
import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests;
|
||||
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
|
||||
|
||||
/**
|
||||
* EclipseLink-specific JPA tests.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class EclipseLinkEntityManagerFactoryIntegrationTests extends AbstractContainerEntityManagerFactoryIntegrationTests {
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return ECLIPSELINK_CONFIG_LOCATIONS;
|
||||
}
|
||||
|
||||
|
||||
public void testCanCastNativeEntityManagerFactoryToTopLinkEntityManagerFactoryImpl() {
|
||||
EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory;
|
||||
assertTrue(emfi.getNativeEntityManagerFactory().getClass().getName().endsWith("EntityManagerFactoryImpl"));
|
||||
}
|
||||
|
||||
public void testCanCastSharedEntityManagerProxyToTopLinkEntityManager() {
|
||||
assertTrue(sharedEntityManager instanceof JpaEntityManager);
|
||||
JpaEntityManager eclipselinkEntityManager = (JpaEntityManager) sharedEntityManager;
|
||||
assertNotNull(eclipselinkEntityManager.getActiveSession());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
<property name="persistenceXmlLocation" value="org/springframework/orm/jpa/domain/persistence.xml"/>
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="jpaVendorAdapter">
|
||||
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
|
||||
<property name="database" value="HSQL"/>
|
||||
<property name="showSql" value="true"/>
|
||||
<property name="generateDdl" value="true"/>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.hibernate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.ejb.HibernateEntityManager;
|
||||
import org.hibernate.ejb.HibernateEntityManagerFactory;
|
||||
import org.junit.Ignore;
|
||||
|
||||
import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests;
|
||||
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
|
||||
import org.springframework.orm.jpa.domain.Person;
|
||||
|
||||
/**
|
||||
* Hibernate-specific JPA tests.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
@Ignore // cannot find AnnotationBeanConfigurerAspect
|
||||
public class HibernateEntityManagerFactoryIntegrationTests extends
|
||||
AbstractContainerEntityManagerFactoryIntegrationTests {
|
||||
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
|
||||
public void setSessionFactory(SessionFactory sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
}
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return HIBERNATE_CONFIG_LOCATIONS;
|
||||
}
|
||||
|
||||
|
||||
public void testCanCastNativeEntityManagerFactoryToHibernateEntityManagerFactoryImpl() {
|
||||
EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory;
|
||||
assertTrue(emfi.getNativeEntityManagerFactory() instanceof HibernateEntityManagerFactory);
|
||||
}
|
||||
|
||||
public void testCanCastSharedEntityManagerProxyToHibernateEntityManager() {
|
||||
assertTrue(sharedEntityManager instanceof HibernateEntityManager);
|
||||
HibernateEntityManager hibernateEntityManager = (HibernateEntityManager) sharedEntityManager;
|
||||
assertNotNull(hibernateEntityManager.getSession());
|
||||
}
|
||||
|
||||
public void testWithHibernateSessionFactory() {
|
||||
// Add with JDBC
|
||||
String firstName = "Tony";
|
||||
insertPerson(firstName);
|
||||
|
||||
Query q = this.sessionFactory.getCurrentSession().createQuery("select p from Person as p");
|
||||
List<Person> people = q.list();
|
||||
|
||||
assertEquals(1, people.size());
|
||||
assertEquals(firstName, people.get(0).getFirstName());
|
||||
}
|
||||
|
||||
public void testConfigurablePerson() {
|
||||
Query q = this.sessionFactory.getCurrentSession().createQuery("select p from ContextualPerson as p");
|
||||
assertEquals(0, q.list().size());
|
||||
//assertNotNull(new ContextualPerson().entityManager); TODO
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.hibernate;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests;
|
||||
|
||||
/**
|
||||
* Hibernate-specific JPA tests with multiple EntityManagerFactory instances.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class HibernateMultiEntityManagerFactoryIntegrationTests extends
|
||||
AbstractContainerEntityManagerFactoryIntegrationTests {
|
||||
|
||||
private EntityManagerFactory entityManagerFactory2;
|
||||
|
||||
|
||||
public HibernateMultiEntityManagerFactoryIntegrationTests() {
|
||||
setAutowireMode(AUTOWIRE_BY_NAME);
|
||||
}
|
||||
|
||||
public void setEntityManagerFactory2(EntityManagerFactory entityManagerFactory2) {
|
||||
this.entityManagerFactory2 = entityManagerFactory2;
|
||||
}
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return new String[] {
|
||||
"/org/springframework/orm/jpa/hibernate/hibernate-manager-multi.xml",
|
||||
"/org/springframework/orm/jpa/memdb.xml",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void testEntityManagerFactory2() {
|
||||
EntityManager em = this.entityManagerFactory2.createEntityManager();
|
||||
try {
|
||||
em.createQuery("select tb from TestBean");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
finally {
|
||||
em.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<import resource="classpath:/org/springframework/orm/jpa/multi-jpa-emf.xml"/>
|
||||
|
||||
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
|
||||
<property name="database" value="HSQL"/>
|
||||
<property name="showSql" value="true"/>
|
||||
<property name="generateDdl" value="true"/>
|
||||
</bean>
|
||||
|
||||
<bean id="jpaProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
|
||||
<property name="properties">
|
||||
<props>
|
||||
<prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
|
||||
|
||||
<context:load-time-weaver aspectj-weaving="on"/>
|
||||
|
||||
<context:annotation-config/>
|
||||
|
||||
<context:spring-configured/>
|
||||
|
||||
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
|
||||
depends-on="org.springframework.context.config.internalBeanConfigurerAspect">
|
||||
<property name="persistenceXmlLocation" value="org/springframework/orm/jpa/domain/persistence-context.xml"/>
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="jpaVendorAdapter">
|
||||
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
|
||||
<property name="database" value="HSQL"/>
|
||||
<property name="showSql" value="true"/>
|
||||
<property name="generateDdl" value="true"/>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="jpaPropertyMap">
|
||||
<props>
|
||||
<prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
|
||||
<!--
|
||||
<prop key="hibernate.ejb.use_class_enhancer">true</prop>
|
||||
-->
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="packagesToScan" value="org.springframework.orm.jpa.domain"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
|
||||
|
||||
<context:annotation-config/>
|
||||
|
||||
<bean id="dao" class="org.springframework.orm.jpa.support.PersistenceInjectionTests$DefaultPublicPersistenceUnitSetterNamedPerson"/>
|
||||
|
||||
<bean class="org.springframework.orm.jpa.support.PersistenceInjectionTests$DefaultPublicPersistenceContextSetter"/>
|
||||
|
||||
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor">
|
||||
<property name="proxyTargetClass" value="true"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" lazy-init="true">
|
||||
<property name="targetObject" ref="dao"/>
|
||||
<property name="targetMethod" value="toString"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,2 @@
|
||||
INSERT INTO PERSON (ID, FIRST_NAME, LAST_NAME) VALUES (1, 'Tony', 'Blair');
|
||||
INSERT INTO DRIVERS_LICENSE (ID, SERIAL_NUMBER) VALUES (1, '8439DK');
|
||||
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory"/>
|
||||
</bean>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory"/>
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
|
||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
||||
<property name="url" value="jdbc:hsqldb:mem:xdb"/>
|
||||
<property name="username" value="sa"/>
|
||||
<property name="password" value=""/>
|
||||
</bean>
|
||||
|
||||
<!-- Datasource for using an existing database. make sure you turn off generateDLL otherwise
|
||||
on multiple runs it will break it.
|
||||
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
|
||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
||||
<property name="url" value="jdbc:hsqldb:file:target/classes/db/test"/>
|
||||
<property name="username" value="sa"/>
|
||||
<property name="password" value=""/>
|
||||
</bean>
|
||||
-->
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
|
||||
<property name="persistenceXmlLocations" value="org/springframework/orm/jpa/domain/persistence-multi.xml"/>
|
||||
<property name="defaultDataSource" ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="abstractEMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" abstract="true">
|
||||
<property name="persistenceUnitManager" ref="persistenceUnitManager"/>
|
||||
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
|
||||
<property name="jpaProperties" ref="jpaProperties"/>
|
||||
</bean>
|
||||
|
||||
<bean id="entityManagerFactory" parent="abstractEMF">
|
||||
<property name="persistenceUnitName" value="Drivers"/>
|
||||
</bean>
|
||||
|
||||
<bean id="entityManagerFactory2" parent="abstractEMF">
|
||||
<property name="persistenceUnitName" value="Test"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.openjpa;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.FlushModeType;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManager;
|
||||
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
|
||||
|
||||
import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests;
|
||||
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
|
||||
import org.springframework.orm.jpa.SharedEntityManagerCreator;
|
||||
import org.springframework.orm.jpa.domain.Person;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
/**
|
||||
* OpenJPA-specific JPA tests.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class OpenJpaEntityManagerFactoryIntegrationTests extends AbstractContainerEntityManagerFactoryIntegrationTests {
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return OPENJPA_CONFIG_LOCATIONS;
|
||||
}
|
||||
|
||||
public void testCanCastNativeEntityManagerFactoryToOpenJpaEntityManagerFactoryImpl() {
|
||||
EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory;
|
||||
assertTrue("native EMF expected", emfi.getNativeEntityManagerFactory() instanceof OpenJPAEntityManagerFactory);
|
||||
}
|
||||
|
||||
public void testCanCastSharedEntityManagerProxyToOpenJpaEntityManager() {
|
||||
assertTrue("native EM expected", sharedEntityManager instanceof OpenJPAEntityManager);
|
||||
}
|
||||
|
||||
public void testCanGetSharedOpenJpaEntityManagerProxy() {
|
||||
OpenJPAEntityManager openJPAEntityManager = (OpenJPAEntityManager) SharedEntityManagerCreator.createSharedEntityManager(
|
||||
entityManagerFactory, null, OpenJPAEntityManager.class);
|
||||
assertNotNull(openJPAEntityManager.getDelegate());
|
||||
}
|
||||
|
||||
public void testSavepoint() {
|
||||
TransactionTemplate tt = new TransactionTemplate(transactionManager);
|
||||
tt.setPropagationBehavior(TransactionTemplate.PROPAGATION_NESTED);
|
||||
tt.execute(new TransactionCallbackWithoutResult() {
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
Person tony = new Person();
|
||||
tony.setFirstName("Tony");
|
||||
sharedEntityManager.merge(tony);
|
||||
Query q = sharedEntityManager.createQuery("select p from Person as p");
|
||||
q.setFlushMode(FlushModeType.COMMIT);
|
||||
List<Person> people = q.getResultList();
|
||||
assertEquals(1, people.size());
|
||||
assertEquals("Tony", people.get(0).getFirstName());
|
||||
status.setRollbackOnly();
|
||||
}
|
||||
});
|
||||
Query q = sharedEntityManager.createQuery("select p from Person as p");
|
||||
List<Person> people = q.getResultList();
|
||||
assertEquals(0, people.size());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.openjpa;
|
||||
|
||||
/**
|
||||
* Test that AspectJ weaving (in particular the currently shipped aspects) work with JPA (see SPR-3873 for more details).
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
*/
|
||||
public class OpenJpaEntityManagerFactoryWithAspectJWeavingIntegrationTests extends OpenJpaEntityManagerFactoryIntegrationTests {
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return new String[] {
|
||||
"/org/springframework/orm/jpa/openjpa/openjpa-manager-aspectj-weaving.xml",
|
||||
"/org/springframework/orm/jpa/memdb.xml",
|
||||
"/org/springframework/orm/jpa/inject.xml"};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
|
||||
|
||||
<context:load-time-weaver aspectj-weaving="on"/>
|
||||
|
||||
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
<property name="persistenceXmlLocation" value="org/springframework/orm/jpa/domain/persistence.xml"/>
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="jpaVendorAdapter">
|
||||
<bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
|
||||
<property name="database" value="HSQL"/>
|
||||
<property name="showSql" value="true"/>
|
||||
<property name="generateDdl" value="true"/>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
<property name="persistenceXmlLocation" value="org/springframework/orm/jpa/domain/persistence.xml"/>
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="jpaVendorAdapter">
|
||||
<bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
|
||||
<property name="database" value="HSQL"/>
|
||||
<property name="showSql" value="true"/>
|
||||
<property name="generateDdl" value="true"/>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,30 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit name="pu1" transaction-type="RESOURCE_LOCAL">
|
||||
<description>
|
||||
This unit manages inventory for auto parts. It depends on
|
||||
features provided by the com.acme.persistence
|
||||
implementation.
|
||||
</description>
|
||||
<provider> com.acme.AcmePersistence</provider>
|
||||
<jta-data-source>jdbc/MyPartDB</jta-data-source>
|
||||
<mapping-file> ormap2.xml</mapping-file>
|
||||
<jar-file> order.jar </jar-file>
|
||||
<properties>
|
||||
<property name="com.acme.persistence.sql-logging" value="on"/>
|
||||
<property name="foo" value="bar" />
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
<persistence-unit name="pu2" transaction-type="JTA">
|
||||
<provider> com.acme.AcmePersistence </provider>
|
||||
<non-jta-data-source>jdbc/MyDB </non-jta-data-source>
|
||||
<mapping-file>order2.xml </mapping-file>
|
||||
<jar-file> order-*.jar</jar-file>
|
||||
<exclude-unlisted-classes />
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
@@ -0,0 +1,8 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
|
||||
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit name="OrderManagement" />
|
||||
</persistence>
|
||||
@@ -0,0 +1,10 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit name="OrderManagement2">
|
||||
<mapping-file>mappings.xml</mapping-file>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
@@ -0,0 +1,11 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit name="OrderManagement3">
|
||||
<jar-file>order.jar</jar-file>
|
||||
<jar-file>order-supplemental.jar</jar-file>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
@@ -0,0 +1,18 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit name="OrderManagement4"
|
||||
transaction-type="RESOURCE_LOCAL">
|
||||
<non-jta-data-source>jdbc/MyDB</non-jta-data-source>
|
||||
<mapping-file>order-mappings.xml</mapping-file>
|
||||
|
||||
<class>com.acme.Order</class>
|
||||
<class>com.acme.Customer</class>
|
||||
<class>com.acme.Item</class>
|
||||
<exclude-unlisted-classes />
|
||||
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
@@ -0,0 +1,14 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit name="OrderManagement5">
|
||||
<provider>com.acme.AcmePersistence</provider>
|
||||
<mapping-file>order1.xml</mapping-file>
|
||||
<mapping-file>order2.xml</mapping-file>
|
||||
<jar-file>order.jar</jar-file>
|
||||
<jar-file>order-supplemental.jar</jar-file>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
@@ -0,0 +1,11 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit name="pu">
|
||||
<properties>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
@@ -0,0 +1,8 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit/>
|
||||
|
||||
</persistence>
|
||||
@@ -0,0 +1,3 @@
|
||||
<persistence>
|
||||
<persistence-unit name="pu1"/>
|
||||
</persistence>
|
||||
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.persistenceunit;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.persistence.spi.PersistenceUnitInfo;
|
||||
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.UrlResource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
|
||||
import org.springframework.jdbc.datasource.lookup.MapDataSourceLookup;
|
||||
import org.springframework.mock.jndi.SimpleNamingContextBuilder;
|
||||
|
||||
/**
|
||||
* Unit and integration tests for the JPA XML resource parsing support.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class PersistenceXmlParsingTests extends TestCase {
|
||||
|
||||
public void testExample1() throws Exception {
|
||||
PersistenceUnitReader reader = new PersistenceUnitReader(
|
||||
new PathMatchingResourcePatternResolver(), new JndiDataSourceLookup());
|
||||
String resource = "/org/springframework/orm/jpa/persistence-example1.xml";
|
||||
PersistenceUnitInfo[] info = reader.readPersistenceUnitInfos(resource);
|
||||
|
||||
assertNotNull(info);
|
||||
assertEquals(1, info.length);
|
||||
assertEquals("OrderManagement", info[0].getPersistenceUnitName());
|
||||
}
|
||||
|
||||
public void testExample2() throws Exception {
|
||||
PersistenceUnitReader reader = new PersistenceUnitReader(
|
||||
new PathMatchingResourcePatternResolver(), new JndiDataSourceLookup());
|
||||
String resource = "/org/springframework/orm/jpa/persistence-example2.xml";
|
||||
PersistenceUnitInfo[] info = reader.readPersistenceUnitInfos(resource);
|
||||
|
||||
assertNotNull(info);
|
||||
assertEquals(1, info.length);
|
||||
|
||||
assertEquals("OrderManagement2", info[0].getPersistenceUnitName());
|
||||
|
||||
assertEquals(1, info[0].getMappingFileNames().size());
|
||||
assertEquals("mappings.xml", info[0].getMappingFileNames().get(0));
|
||||
assertEquals(0, info[0].getProperties().keySet().size());
|
||||
}
|
||||
|
||||
public void testExample3() throws Exception {
|
||||
PersistenceUnitReader reader = new PersistenceUnitReader(
|
||||
new PathMatchingResourcePatternResolver(), new JndiDataSourceLookup());
|
||||
String resource = "/org/springframework/orm/jpa/persistence-example3.xml";
|
||||
PersistenceUnitInfo[] info = reader.readPersistenceUnitInfos(resource);
|
||||
|
||||
assertNotNull(info);
|
||||
assertEquals(1, info.length);
|
||||
assertEquals("OrderManagement3", info[0].getPersistenceUnitName());
|
||||
|
||||
assertEquals(2, info[0].getJarFileUrls().size());
|
||||
assertEquals(new ClassPathResource("order.jar").getURL(), info[0].getJarFileUrls().get(0));
|
||||
assertEquals(new ClassPathResource("order-supplemental.jar").getURL(), info[0].getJarFileUrls().get(1));
|
||||
assertEquals(0, info[0].getProperties().keySet().size());
|
||||
assertNull(info[0].getJtaDataSource());
|
||||
assertNull(info[0].getNonJtaDataSource());
|
||||
}
|
||||
|
||||
public void testExample4() throws Exception {
|
||||
SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
|
||||
DataSource ds = new DriverManagerDataSource();
|
||||
builder.bind("java:comp/env/jdbc/MyDB", ds);
|
||||
|
||||
PersistenceUnitReader reader = new PersistenceUnitReader(
|
||||
new PathMatchingResourcePatternResolver(), new JndiDataSourceLookup());
|
||||
String resource = "/org/springframework/orm/jpa/persistence-example4.xml";
|
||||
PersistenceUnitInfo[] info = reader.readPersistenceUnitInfos(resource);
|
||||
|
||||
assertNotNull(info);
|
||||
assertEquals(1, info.length);
|
||||
assertEquals("OrderManagement4", info[0].getPersistenceUnitName());
|
||||
|
||||
assertEquals(1, info[0].getMappingFileNames().size());
|
||||
assertEquals("order-mappings.xml", info[0].getMappingFileNames().get(0));
|
||||
|
||||
assertEquals(3, info[0].getManagedClassNames().size());
|
||||
assertEquals("com.acme.Order", info[0].getManagedClassNames().get(0));
|
||||
assertEquals("com.acme.Customer", info[0].getManagedClassNames().get(1));
|
||||
assertEquals("com.acme.Item", info[0].getManagedClassNames().get(2));
|
||||
|
||||
assertTrue(info[0].excludeUnlistedClasses());
|
||||
|
||||
assertSame(PersistenceUnitTransactionType.RESOURCE_LOCAL, info[0].getTransactionType());
|
||||
assertEquals(0, info[0].getProperties().keySet().size());
|
||||
|
||||
// TODO this is undefined as yet. Do we look up Spring datasource?
|
||||
// assertNotNull(info[0].getNonJtaDataSource());
|
||||
//
|
||||
// assertEquals(ds .toString(),
|
||||
// info[0].getNonJtaDataSource().toString());
|
||||
|
||||
builder.clear();
|
||||
}
|
||||
|
||||
public void testExample5() throws Exception {
|
||||
PersistenceUnitReader reader = new PersistenceUnitReader(
|
||||
new PathMatchingResourcePatternResolver(), new JndiDataSourceLookup());
|
||||
String resource = "/org/springframework/orm/jpa/persistence-example5.xml";
|
||||
PersistenceUnitInfo[] info = reader.readPersistenceUnitInfos(resource);
|
||||
|
||||
assertNotNull(info);
|
||||
assertEquals(1, info.length);
|
||||
assertEquals("OrderManagement5", info[0].getPersistenceUnitName());
|
||||
|
||||
assertEquals(2, info[0].getMappingFileNames().size());
|
||||
assertEquals("order1.xml", info[0].getMappingFileNames().get(0));
|
||||
assertEquals("order2.xml", info[0].getMappingFileNames().get(1));
|
||||
|
||||
assertEquals(2, info[0].getJarFileUrls().size());
|
||||
assertEquals(new ClassPathResource("order.jar").getURL(), info[0].getJarFileUrls().get(0));
|
||||
assertEquals(new ClassPathResource("order-supplemental.jar").getURL(), info[0].getJarFileUrls().get(1));
|
||||
|
||||
assertEquals("com.acme.AcmePersistence", info[0].getPersistenceProviderClassName());
|
||||
assertEquals(0, info[0].getProperties().keySet().size());
|
||||
}
|
||||
|
||||
public void testExampleComplex() throws Exception {
|
||||
DataSource ds = new DriverManagerDataSource();
|
||||
|
||||
String resource = "/org/springframework/orm/jpa/persistence-complex.xml";
|
||||
MapDataSourceLookup dataSourceLookup = new MapDataSourceLookup();
|
||||
Map<String, DataSource> dataSources = new HashMap<String, DataSource>();
|
||||
dataSources.put("jdbc/MyPartDB", ds);
|
||||
dataSources.put("jdbc/MyDB", ds);
|
||||
dataSourceLookup.setDataSources(dataSources);
|
||||
PersistenceUnitReader reader = new PersistenceUnitReader(
|
||||
new PathMatchingResourcePatternResolver(), dataSourceLookup);
|
||||
PersistenceUnitInfo[] info = reader.readPersistenceUnitInfos(resource);
|
||||
|
||||
assertEquals(2, info.length);
|
||||
|
||||
PersistenceUnitInfo pu1 = info[0];
|
||||
|
||||
assertEquals("pu1", pu1.getPersistenceUnitName());
|
||||
|
||||
assertEquals("com.acme.AcmePersistence", pu1.getPersistenceProviderClassName());
|
||||
|
||||
assertEquals(1, pu1.getMappingFileNames().size());
|
||||
assertEquals("ormap2.xml", pu1.getMappingFileNames().get(0));
|
||||
|
||||
assertEquals(1, pu1.getJarFileUrls().size());
|
||||
assertEquals(new ClassPathResource("order.jar").getURL(), pu1.getJarFileUrls().get(0));
|
||||
|
||||
// TODO need to check the default? Where is this defined
|
||||
assertFalse(pu1.excludeUnlistedClasses());
|
||||
|
||||
assertSame(PersistenceUnitTransactionType.RESOURCE_LOCAL, pu1.getTransactionType());
|
||||
|
||||
Properties props = pu1.getProperties();
|
||||
assertEquals(2, props.keySet().size());
|
||||
assertEquals("on", props.getProperty("com.acme.persistence.sql-logging"));
|
||||
assertEquals("bar", props.getProperty("foo"));
|
||||
|
||||
assertNull(pu1.getNonJtaDataSource());
|
||||
|
||||
assertSame(ds, pu1.getJtaDataSource());
|
||||
|
||||
PersistenceUnitInfo pu2 = info[1];
|
||||
|
||||
assertSame(PersistenceUnitTransactionType.JTA, pu2.getTransactionType());
|
||||
assertEquals("com.acme.AcmePersistence", pu2.getPersistenceProviderClassName());
|
||||
|
||||
assertEquals(1, pu2.getMappingFileNames().size());
|
||||
assertEquals("order2.xml", pu2.getMappingFileNames().get(0));
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
Ignore ignore; // the following assertions fail only during coverage runs
|
||||
/*
|
||||
assertEquals(1, pu2.getJarFileUrls().size());
|
||||
assertEquals(new ClassPathResource("order-supplemental.jar").getURL(), pu2.getJarFileUrls().get(0));
|
||||
assertTrue(pu2.excludeUnlistedClasses());
|
||||
|
||||
assertNull(pu2.getJtaDataSource());
|
||||
|
||||
// TODO need to define behaviour with non jta datasource
|
||||
assertEquals(ds, pu2.getNonJtaDataSource());
|
||||
*/
|
||||
}
|
||||
|
||||
public void testExample6() throws Exception {
|
||||
PersistenceUnitReader reader = new PersistenceUnitReader(
|
||||
new PathMatchingResourcePatternResolver(), new JndiDataSourceLookup());
|
||||
String resource = "/org/springframework/orm/jpa/persistence-example6.xml";
|
||||
PersistenceUnitInfo[] info = reader.readPersistenceUnitInfos(resource);
|
||||
assertEquals(1, info.length);
|
||||
assertEquals("pu", info[0].getPersistenceUnitName());
|
||||
assertEquals(0, info[0].getProperties().keySet().size());
|
||||
}
|
||||
|
||||
public void testInvalidPersistence() throws Exception {
|
||||
PersistenceUnitReader reader = new PersistenceUnitReader(
|
||||
new PathMatchingResourcePatternResolver(), new JndiDataSourceLookup());
|
||||
String resource = "/org/springframework/orm/jpa/persistence-invalid.xml";
|
||||
try {
|
||||
reader.readPersistenceUnitInfos(resource);
|
||||
fail("expected invalid document exception");
|
||||
}
|
||||
catch (RuntimeException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testNoSchemaPersistence() throws Exception {
|
||||
PersistenceUnitReader reader = new PersistenceUnitReader(
|
||||
new PathMatchingResourcePatternResolver(), new JndiDataSourceLookup());
|
||||
String resource = "/org/springframework/orm/jpa/persistence-no-schema.xml";
|
||||
try {
|
||||
reader.readPersistenceUnitInfos(resource);
|
||||
fail("expected invalid document exception");
|
||||
}
|
||||
catch (RuntimeException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testPersistenceUnitRootUrl() throws Exception {
|
||||
PersistenceUnitReader reader = new PersistenceUnitReader(
|
||||
new PathMatchingResourcePatternResolver(), new JndiDataSourceLookup());
|
||||
|
||||
URL url = reader.determinePersistenceUnitRootUrl(new ClassPathResource(
|
||||
"/org/springframework/orm/jpa/persistence-no-schema.xml"));
|
||||
assertNull(url);
|
||||
|
||||
url = reader.determinePersistenceUnitRootUrl(new ClassPathResource("/org/springframework/orm/jpa/META-INF/persistence.xml"));
|
||||
assertTrue("the containing folder should have been returned", url.toString().endsWith("/org/springframework/orm/jpa/"));
|
||||
}
|
||||
|
||||
public void testPersistenceUnitRootUrlWithJar() throws Exception {
|
||||
PersistenceUnitReader reader = new PersistenceUnitReader(
|
||||
new PathMatchingResourcePatternResolver(), new JndiDataSourceLookup());
|
||||
|
||||
ClassPathResource archive = new ClassPathResource("/org/springframework/orm/jpa/jpa-archive.jar");
|
||||
String newRoot = "jar:" + archive.getURL().toExternalForm() + "!/META-INF/persist.xml";
|
||||
Resource insideArchive = new UrlResource(newRoot);
|
||||
// make sure the location actually exists
|
||||
assertTrue(insideArchive.exists());
|
||||
URL url = reader.determinePersistenceUnitRootUrl(insideArchive);
|
||||
assertTrue("the archive location should have been returned", archive.getURL().sameFile(url));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.orm.jpa.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.orm.jpa.JpaTemplate;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*
|
||||
*/
|
||||
public class JpaDaoSupportTests extends TestCase {
|
||||
|
||||
public void testJpaDaoSupportWithEntityManager() throws Exception {
|
||||
MockControl mockControl = MockControl.createControl(EntityManager.class);
|
||||
EntityManager entityManager = (EntityManager) mockControl.getMock();
|
||||
mockControl.replay();
|
||||
final List test = new ArrayList();
|
||||
JpaDaoSupport dao = new JpaDaoSupport() {
|
||||
protected void initDao() {
|
||||
test.add("test");
|
||||
}
|
||||
};
|
||||
dao.setEntityManager(entityManager);
|
||||
dao.afterPropertiesSet();
|
||||
assertNotNull("jpa template not created", dao.getJpaTemplate());
|
||||
assertEquals("incorrect entity manager", entityManager, dao.getJpaTemplate().getEntityManager());
|
||||
assertEquals("initDao not called", test.size(), 1);
|
||||
mockControl.verify();
|
||||
}
|
||||
|
||||
public void testJpaDaoSupportWithEntityManagerFactory() throws Exception {
|
||||
MockControl mockControl = MockControl.createControl(EntityManagerFactory.class);
|
||||
EntityManagerFactory entityManagerFactory = (EntityManagerFactory) mockControl.getMock();
|
||||
mockControl.replay();
|
||||
final List test = new ArrayList();
|
||||
JpaDaoSupport dao = new JpaDaoSupport() {
|
||||
protected void initDao() {
|
||||
test.add("test");
|
||||
}
|
||||
};
|
||||
dao.setEntityManagerFactory(entityManagerFactory);
|
||||
dao.afterPropertiesSet();
|
||||
assertNotNull("jpa template not created", dao.getJpaTemplate());
|
||||
assertEquals("incorrect entity manager factory", entityManagerFactory,
|
||||
dao.getJpaTemplate().getEntityManagerFactory());
|
||||
assertEquals("initDao not called", test.size(), 1);
|
||||
mockControl.verify();
|
||||
}
|
||||
|
||||
public void testJpaDaoSupportWithJpaTemplate() throws Exception {
|
||||
JpaTemplate template = new JpaTemplate();
|
||||
final List test = new ArrayList();
|
||||
JpaDaoSupport dao = new JpaDaoSupport() {
|
||||
protected void initDao() {
|
||||
test.add("test");
|
||||
}
|
||||
};
|
||||
dao.setJpaTemplate(template);
|
||||
dao.afterPropertiesSet();
|
||||
assertNotNull("jpa template not created", dao.getJpaTemplate());
|
||||
assertEquals("incorrect JpaTemplate", template, dao.getJpaTemplate());
|
||||
assertEquals("initDao not called", test.size(), 1);
|
||||
}
|
||||
|
||||
public void testInvalidJpaTemplate() throws Exception {
|
||||
JpaDaoSupport dao = new JpaDaoSupport() {
|
||||
};
|
||||
try {
|
||||
dao.afterPropertiesSet();
|
||||
fail("expected exception");
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
// okay
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.support;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
@Ignore // dependency issues after moving from .testsuite -> .test
|
||||
public class OpenEntityManagerInViewTests {
|
||||
|
||||
// private MockControl factoryControl, managerControl;
|
||||
//
|
||||
// private EntityManager manager;
|
||||
//
|
||||
// private EntityManagerFactory factory;
|
||||
//
|
||||
// private JpaTemplate template;
|
||||
//
|
||||
//
|
||||
// @Override
|
||||
// protected void setUp() throws Exception {
|
||||
// factoryControl = MockControl.createControl(EntityManagerFactory.class);
|
||||
// factory = (EntityManagerFactory) factoryControl.getMock();
|
||||
// managerControl = MockControl.createControl(EntityManager.class);
|
||||
// manager = (EntityManager) managerControl.getMock();
|
||||
//
|
||||
// template = new JpaTemplate(factory);
|
||||
// template.afterPropertiesSet();
|
||||
//
|
||||
// factoryControl.expectAndReturn(factory.createEntityManager(), manager);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void tearDown() throws Exception {
|
||||
// assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
|
||||
// assertFalse(TransactionSynchronizationManager.isSynchronizationActive());
|
||||
// assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
|
||||
// assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
|
||||
// }
|
||||
//
|
||||
// public void testOpenEntityManagerInterceptorInView() throws Exception {
|
||||
// OpenEntityManagerInViewInterceptor rawInterceptor = new OpenEntityManagerInViewInterceptor();
|
||||
// rawInterceptor.setEntityManagerFactory(factory);
|
||||
// HandlerInterceptor interceptor = new WebRequestHandlerInterceptorAdapter(rawInterceptor);
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// managerControl.replay();
|
||||
// factoryControl.replay();
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||
//
|
||||
// // check that further invocations simply participate
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// interceptor.preHandle(request, response, "handler");
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
//
|
||||
// factoryControl.verify();
|
||||
// managerControl.verify();
|
||||
//
|
||||
// managerControl.reset();
|
||||
// factoryControl.reset();
|
||||
// managerControl.replay();
|
||||
// factoryControl.replay();
|
||||
//
|
||||
// interceptor.postHandle(request, response, "handler", null);
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||
//
|
||||
// factoryControl.verify();
|
||||
// managerControl.verify();
|
||||
//
|
||||
// managerControl.reset();
|
||||
// factoryControl.reset();
|
||||
//
|
||||
// manager.close();
|
||||
//
|
||||
// managerControl.replay();
|
||||
// factoryControl.replay();
|
||||
//
|
||||
// interceptor.afterCompletion(request, response, "handler", null);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(factory));
|
||||
//
|
||||
// factoryControl.verify();
|
||||
// managerControl.verify();
|
||||
// }
|
||||
//
|
||||
// public void testOpenEntityManagerInViewFilter() throws Exception {
|
||||
// manager.close();
|
||||
//
|
||||
// managerControl.replay();
|
||||
// factoryControl.replay();
|
||||
//
|
||||
// MockControl factoryControl2 = MockControl.createControl(EntityManagerFactory.class);
|
||||
// final EntityManagerFactory factory2 = (EntityManagerFactory) factoryControl2.getMock();
|
||||
//
|
||||
// MockControl managerControl2 = MockControl.createControl(EntityManager.class);
|
||||
// EntityManager manager2 = (EntityManager) managerControl2.getMock();
|
||||
//
|
||||
// factoryControl2.expectAndReturn(factory2.createEntityManager(), manager2);
|
||||
// manager2.close();
|
||||
//
|
||||
// factoryControl2.replay();
|
||||
// managerControl2.replay();
|
||||
//
|
||||
// MockServletContext sc = new MockServletContext();
|
||||
// StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
// wac.setServletContext(sc);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", factory);
|
||||
// wac.getDefaultListableBeanFactory().registerSingleton("myEntityManagerFactory", factory2);
|
||||
// wac.refresh();
|
||||
// sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
// MockHttpServletRequest request = new MockHttpServletRequest(sc);
|
||||
// MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
//
|
||||
// MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
|
||||
// MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
|
||||
// filterConfig2.addInitParameter("entityManagerFactoryBeanName", "myEntityManagerFactory");
|
||||
//
|
||||
// final OpenEntityManagerInViewFilter filter = new OpenEntityManagerInViewFilter();
|
||||
// filter.init(filterConfig);
|
||||
// final OpenEntityManagerInViewFilter filter2 = new OpenEntityManagerInViewFilter();
|
||||
// filter2.init(filterConfig2);
|
||||
//
|
||||
// final FilterChain filterChain = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(factory));
|
||||
// servletRequest.setAttribute("invoked", Boolean.TRUE);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// final FilterChain filterChain2 = new FilterChain() {
|
||||
// public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
|
||||
// throws IOException, ServletException {
|
||||
// assertTrue(TransactionSynchronizationManager.hasResource(factory2));
|
||||
// filter.doFilter(servletRequest, servletResponse, filterChain);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
|
||||
//
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(factory));
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(factory2));
|
||||
// filter2.doFilter(request, response, filterChain3);
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(factory));
|
||||
// assertFalse(TransactionSynchronizationManager.hasResource(factory2));
|
||||
// assertNotNull(request.getAttribute("invoked"));
|
||||
//
|
||||
// factoryControl.verify();
|
||||
// managerControl.verify();
|
||||
// factoryControl2.verify();
|
||||
// managerControl2.verify();
|
||||
//
|
||||
// wac.close();
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.support;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.orm.jpa.AbstractEntityManagerFactoryIntegrationTests;
|
||||
import org.springframework.orm.jpa.support.PersistenceInjectionTests.DefaultPublicPersistenceContextSetter;
|
||||
import org.springframework.orm.jpa.support.PersistenceInjectionTests.DefaultPublicPersistenceUnitSetterNamedPerson;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class PersistenceInjectionIntegrationTests extends AbstractEntityManagerFactoryIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private DefaultPublicPersistenceContextSetter defaultSetterInjected;
|
||||
|
||||
private DefaultPublicPersistenceUnitSetterNamedPerson namedSetterInjected;
|
||||
|
||||
|
||||
public PersistenceInjectionIntegrationTests() {
|
||||
setAutowireMode(AUTOWIRE_NO);
|
||||
setDependencyCheck(false);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private void init(DefaultPublicPersistenceUnitSetterNamedPerson namedSetterInjected) {
|
||||
this.namedSetterInjected = namedSetterInjected;
|
||||
}
|
||||
|
||||
|
||||
public void testDefaultSetterInjection() {
|
||||
EntityManager injectedEm = defaultSetterInjected.getEntityManager();
|
||||
assertNotNull("Default PersistenceContext Setter was injected", injectedEm);
|
||||
}
|
||||
|
||||
public void testInjectedEntityManagerImplmentsPortableEntityManagerPlus() {
|
||||
EntityManager injectedEm = defaultSetterInjected.getEntityManager();
|
||||
assertNotNull("Default PersistenceContext Setter was injected", injectedEm);
|
||||
}
|
||||
|
||||
public void testSetterInjectionOfNamedPersistenceContext() {
|
||||
assertNotNull("Named PersistenceContext Setter was injected", namedSetterInjected.getEntityManagerFactory());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,847 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.PersistenceContextType;
|
||||
import javax.persistence.PersistenceProperty;
|
||||
import javax.persistence.PersistenceUnit;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.hibernate.ejb.HibernateEntityManager;
|
||||
import org.junit.Ignore;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.config.SimpleMapScope;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.mock.jndi.ExpectedLookupTemplate;
|
||||
import org.springframework.orm.jpa.AbstractEntityManagerFactoryBeanTests;
|
||||
import org.springframework.orm.jpa.DefaultJpaDialect;
|
||||
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
|
||||
import org.springframework.orm.jpa.EntityManagerHolder;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.SerializationTestUtils;
|
||||
|
||||
/**
|
||||
* Unit tests for persistence context and persistence unit injection.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanTests {
|
||||
|
||||
public void testPrivatePersistenceContextField() {
|
||||
GenericApplicationContext gac = new GenericApplicationContext();
|
||||
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
|
||||
gac.registerBeanDefinition("annotationProcessor",
|
||||
new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
|
||||
gac.registerBeanDefinition(DefaultPrivatePersistenceContextField.class.getName(),
|
||||
new RootBeanDefinition(DefaultPrivatePersistenceContextField.class));
|
||||
gac.registerBeanDefinition(FactoryBeanWithPersistenceContextField.class.getName(),
|
||||
new RootBeanDefinition(FactoryBeanWithPersistenceContextField.class));
|
||||
gac.refresh();
|
||||
|
||||
DefaultPrivatePersistenceContextField bean = (DefaultPrivatePersistenceContextField) gac.getBean(
|
||||
DefaultPrivatePersistenceContextField.class.getName());
|
||||
FactoryBeanWithPersistenceContextField bean2 = (FactoryBeanWithPersistenceContextField) gac.getBean(
|
||||
"&" + FactoryBeanWithPersistenceContextField.class.getName());
|
||||
assertNotNull(bean.em);
|
||||
assertNotNull(bean2.em);
|
||||
}
|
||||
|
||||
public void testPrivateVendorSpecificPersistenceContextField() {
|
||||
GenericApplicationContext gac = new GenericApplicationContext();
|
||||
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
|
||||
gac.registerBeanDefinition("annotationProcessor",
|
||||
new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
|
||||
gac.registerBeanDefinition(DefaultVendorSpecificPrivatePersistenceContextField.class.getName(),
|
||||
new RootBeanDefinition(DefaultVendorSpecificPrivatePersistenceContextField.class));
|
||||
gac.refresh();
|
||||
|
||||
DefaultVendorSpecificPrivatePersistenceContextField bean = (DefaultVendorSpecificPrivatePersistenceContextField)
|
||||
gac.getBean(DefaultVendorSpecificPrivatePersistenceContextField.class.getName());
|
||||
assertNotNull(bean.em);
|
||||
}
|
||||
|
||||
public void testPublicExtendedPersistenceContextSetter() throws Exception {
|
||||
Object mockEm = (EntityManager) MockControl.createControl(EntityManager.class).getMock();
|
||||
mockEmf.createEntityManager();
|
||||
emfMc.setReturnValue(mockEm, 1);
|
||||
emfMc.replay();
|
||||
|
||||
GenericApplicationContext gac = new GenericApplicationContext();
|
||||
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
|
||||
gac.registerBeanDefinition("annotationProcessor",
|
||||
new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
|
||||
gac.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class));
|
||||
gac.refresh();
|
||||
|
||||
DefaultPublicPersistenceContextSetter bean = (DefaultPublicPersistenceContextSetter) gac.getBean(
|
||||
DefaultPublicPersistenceContextSetter.class.getName());
|
||||
assertNotNull(bean.em);
|
||||
emfMc.verify();
|
||||
}
|
||||
|
||||
public void testPublicExtendedPersistenceContextSetterWithSerialization() throws Exception {
|
||||
DummyInvocationHandler ih = new DummyInvocationHandler();
|
||||
Object mockEm = (EntityManager) Proxy.newProxyInstance(
|
||||
getClass().getClassLoader(), new Class[] {EntityManager.class}, ih);
|
||||
mockEmf.createEntityManager();
|
||||
emfMc.setReturnValue(mockEm, 1);
|
||||
emfMc.replay();
|
||||
|
||||
GenericApplicationContext gac = new GenericApplicationContext();
|
||||
SimpleMapScope myScope = new SimpleMapScope();
|
||||
gac.getDefaultListableBeanFactory().registerScope("myScope", myScope);
|
||||
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
|
||||
gac.registerBeanDefinition("annotationProcessor",
|
||||
new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
|
||||
RootBeanDefinition bd = new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class);
|
||||
bd.setScope("myScope");
|
||||
gac.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(), bd);
|
||||
gac.refresh();
|
||||
|
||||
DefaultPublicPersistenceContextSetter bean = (DefaultPublicPersistenceContextSetter) gac.getBean(
|
||||
DefaultPublicPersistenceContextSetter.class.getName());
|
||||
assertNotNull(bean.em);
|
||||
assertNotNull(SerializationTestUtils.serializeAndDeserialize(bean.em));
|
||||
|
||||
SimpleMapScope serialized = (SimpleMapScope) SerializationTestUtils.serializeAndDeserialize(myScope);
|
||||
serialized.close();
|
||||
assertTrue(DummyInvocationHandler.closed);
|
||||
DummyInvocationHandler.closed = false;
|
||||
emfMc.verify();
|
||||
}
|
||||
|
||||
public void testPublicExtendedPersistenceContextSetterWithEntityManagerInfoAndSerialization() throws Exception {
|
||||
Object mockEm = (EntityManager) Proxy.newProxyInstance(
|
||||
getClass().getClassLoader(), new Class[] {EntityManager.class}, new DummyInvocationHandler());
|
||||
MockControl emfMc = MockControl.createControl(EntityManagerFactoryWithInfo.class);
|
||||
EntityManagerFactoryWithInfo mockEmf = (EntityManagerFactoryWithInfo) emfMc.getMock();
|
||||
mockEmf.getNativeEntityManagerFactory();
|
||||
emfMc.setReturnValue(mockEmf);
|
||||
mockEmf.getPersistenceUnitInfo();
|
||||
emfMc.setReturnValue(null);
|
||||
mockEmf.getJpaDialect();
|
||||
emfMc.setReturnValue(new DefaultJpaDialect());
|
||||
mockEmf.getEntityManagerInterface();
|
||||
emfMc.setReturnValue(EntityManager.class);
|
||||
mockEmf.getBeanClassLoader();
|
||||
emfMc.setReturnValue(getClass().getClassLoader());
|
||||
mockEmf.createEntityManager();
|
||||
emfMc.setReturnValue(mockEm);
|
||||
emfMc.replay();
|
||||
|
||||
GenericApplicationContext gac = new GenericApplicationContext();
|
||||
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
|
||||
gac.registerBeanDefinition("annotationProcessor",
|
||||
new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
|
||||
gac.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class));
|
||||
gac.refresh();
|
||||
|
||||
DefaultPublicPersistenceContextSetter bean = (DefaultPublicPersistenceContextSetter) gac.getBean(
|
||||
DefaultPublicPersistenceContextSetter.class.getName());
|
||||
assertNotNull(bean.em);
|
||||
assertNotNull(SerializationTestUtils.serializeAndDeserialize(bean.em));
|
||||
emfMc.verify();
|
||||
}
|
||||
|
||||
public void testPublicExtendedPersistenceContextSetterWithOverriding() {
|
||||
EntityManager mockEm2 = (EntityManager) MockControl.createControl(EntityManager.class).getMock();
|
||||
|
||||
GenericApplicationContext gac = new GenericApplicationContext();
|
||||
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
|
||||
gac.registerBeanDefinition("annotationProcessor",
|
||||
new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
|
||||
RootBeanDefinition bd = new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class);
|
||||
bd.getPropertyValues().addPropertyValue("entityManager", mockEm2);
|
||||
gac.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(), bd);
|
||||
gac.refresh();
|
||||
|
||||
DefaultPublicPersistenceContextSetter bean = (DefaultPublicPersistenceContextSetter) gac.getBean(
|
||||
DefaultPublicPersistenceContextSetter.class.getName());
|
||||
assertSame(mockEm2, bean.em);
|
||||
}
|
||||
|
||||
public void testPrivatePersistenceUnitField() {
|
||||
GenericApplicationContext gac = new GenericApplicationContext();
|
||||
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
|
||||
gac.registerBeanDefinition("annotationProcessor",
|
||||
new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
|
||||
gac.registerBeanDefinition(DefaultPrivatePersistenceUnitField.class.getName(),
|
||||
new RootBeanDefinition(DefaultPrivatePersistenceUnitField.class));
|
||||
gac.refresh();
|
||||
|
||||
DefaultPrivatePersistenceUnitField bean = (DefaultPrivatePersistenceUnitField) gac.getBean(
|
||||
DefaultPrivatePersistenceUnitField.class.getName());
|
||||
assertSame(mockEmf, bean.emf);
|
||||
}
|
||||
|
||||
public void testPublicPersistenceUnitSetter() {
|
||||
GenericApplicationContext gac = new GenericApplicationContext();
|
||||
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
|
||||
gac.registerBeanDefinition("annotationProcessor",
|
||||
new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
|
||||
gac.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class));
|
||||
gac.refresh();
|
||||
|
||||
DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter) gac.getBean(
|
||||
DefaultPublicPersistenceUnitSetter.class.getName());
|
||||
assertSame(mockEmf, bean.emf);
|
||||
}
|
||||
|
||||
public void testPublicPersistenceUnitSetterWithOverriding() {
|
||||
EntityManagerFactory mockEmf2 =
|
||||
(EntityManagerFactory) MockControl.createControl(EntityManagerFactory.class).getMock();
|
||||
|
||||
GenericApplicationContext gac = new GenericApplicationContext();
|
||||
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
|
||||
gac.registerBeanDefinition("annotationProcessor",
|
||||
new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
|
||||
RootBeanDefinition bd = new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class);
|
||||
bd.getPropertyValues().addPropertyValue("emf", mockEmf2);
|
||||
gac.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(), bd);
|
||||
gac.refresh();
|
||||
|
||||
DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter) gac.getBean(
|
||||
DefaultPublicPersistenceUnitSetter.class.getName());
|
||||
assertSame(mockEmf2, bean.emf);
|
||||
}
|
||||
|
||||
public void testPublicPersistenceUnitSetterWithUnitIdentifiedThroughBeanName() {
|
||||
EntityManagerFactory mockEmf2 =
|
||||
(EntityManagerFactory) MockControl.createControl(EntityManagerFactory.class).getMock();
|
||||
|
||||
GenericApplicationContext gac = new GenericApplicationContext();
|
||||
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
|
||||
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory2", mockEmf2);
|
||||
gac.registerAlias("entityManagerFactory2", "Person");
|
||||
RootBeanDefinition processorDef = new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class);
|
||||
processorDef.getPropertyValues().addPropertyValue("defaultPersistenceUnitName", "entityManagerFactory");
|
||||
gac.registerBeanDefinition("annotationProcessor", processorDef);
|
||||
gac.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class));
|
||||
gac.registerBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class));
|
||||
gac.refresh();
|
||||
|
||||
DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter)
|
||||
gac.getBean(DefaultPublicPersistenceUnitSetter.class.getName());
|
||||
DefaultPublicPersistenceUnitSetterNamedPerson bean2 = (DefaultPublicPersistenceUnitSetterNamedPerson)
|
||||
gac.getBean(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName());
|
||||
assertSame(mockEmf, bean.emf);
|
||||
assertSame(mockEmf2, bean2.emf);
|
||||
}
|
||||
|
||||
public void testPublicPersistenceUnitSetterWithMultipleUnitsIdentifiedThroughUnitName() {
|
||||
MockControl emf2Mc = MockControl.createControl(EntityManagerFactoryWithInfo.class);
|
||||
EntityManagerFactoryWithInfo mockEmf2 = (EntityManagerFactoryWithInfo) emf2Mc.getMock();
|
||||
mockEmf2.getPersistenceUnitName();
|
||||
emf2Mc.setReturnValue("Person", 2);
|
||||
emf2Mc.replay();
|
||||
|
||||
GenericApplicationContext gac = new GenericApplicationContext();
|
||||
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
|
||||
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory2", mockEmf2);
|
||||
RootBeanDefinition processorDef = new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class);
|
||||
processorDef.getPropertyValues().addPropertyValue("defaultPersistenceUnitName", "entityManagerFactory");
|
||||
gac.registerBeanDefinition("annotationProcessor", processorDef);
|
||||
gac.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class));
|
||||
gac.registerBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class));
|
||||
gac.refresh();
|
||||
|
||||
DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter)
|
||||
gac.getBean(DefaultPublicPersistenceUnitSetter.class.getName());
|
||||
DefaultPublicPersistenceUnitSetterNamedPerson bean2 = (DefaultPublicPersistenceUnitSetterNamedPerson)
|
||||
gac.getBean(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName());
|
||||
assertSame(mockEmf, bean.emf);
|
||||
assertSame(mockEmf2, bean2.emf);
|
||||
|
||||
emf2Mc.verify();
|
||||
}
|
||||
|
||||
@Ignore
|
||||
public void ignoreTestPersistenceUnitsFromJndi() {
|
||||
mockEmf.createEntityManager();
|
||||
Object mockEm = (EntityManager) MockControl.createControl(EntityManager.class).getMock();
|
||||
emfMc.setReturnValue(mockEm, 1);
|
||||
emfMc.replay();
|
||||
|
||||
MockControl emf2Mc = MockControl.createControl(EntityManagerFactoryWithInfo.class);
|
||||
EntityManagerFactoryWithInfo mockEmf2 = (EntityManagerFactoryWithInfo) emf2Mc.getMock();
|
||||
|
||||
Map<String, String> persistenceUnits = new HashMap<String, String>();
|
||||
persistenceUnits.put("", "pu1");
|
||||
persistenceUnits.put("Person", "pu2");
|
||||
ExpectedLookupTemplate jt = new ExpectedLookupTemplate();
|
||||
jt.addObject("java:comp/env/pu1", mockEmf);
|
||||
jt.addObject("java:comp/env/pu2", mockEmf2);
|
||||
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
PersistenceAnnotationBeanPostProcessor bpp = new PersistenceAnnotationBeanPostProcessor();
|
||||
bpp.setPersistenceUnits(persistenceUnits);
|
||||
bpp.setJndiTemplate(jt);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
bf.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class));
|
||||
bf.registerBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class));
|
||||
bf.registerBeanDefinition(DefaultPrivatePersistenceContextField.class.getName(),
|
||||
new RootBeanDefinition(DefaultPrivatePersistenceContextField.class));
|
||||
bf.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class));
|
||||
|
||||
DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter)
|
||||
bf.getBean(DefaultPublicPersistenceUnitSetter.class.getName());
|
||||
DefaultPublicPersistenceUnitSetterNamedPerson bean2 = (DefaultPublicPersistenceUnitSetterNamedPerson)
|
||||
bf.getBean(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName());
|
||||
DefaultPrivatePersistenceContextField bean3 = (DefaultPrivatePersistenceContextField)
|
||||
bf.getBean(DefaultPrivatePersistenceContextField.class.getName());
|
||||
DefaultPublicPersistenceContextSetter bean4 = (DefaultPublicPersistenceContextSetter)
|
||||
bf.getBean(DefaultPublicPersistenceContextSetter.class.getName());
|
||||
assertSame(mockEmf, bean.emf);
|
||||
assertSame(mockEmf2, bean2.emf);
|
||||
assertNotNull(bean3.em);
|
||||
assertNotNull(bean4.em);
|
||||
|
||||
emfMc.verify();
|
||||
}
|
||||
|
||||
public void testPersistenceUnitsFromJndiWithDefaultUnit() {
|
||||
MockControl emf2Mc = MockControl.createControl(EntityManagerFactoryWithInfo.class);
|
||||
EntityManagerFactoryWithInfo mockEmf2 = (EntityManagerFactoryWithInfo) emf2Mc.getMock();
|
||||
|
||||
Map<String, String> persistenceUnits = new HashMap<String, String>();
|
||||
persistenceUnits.put("System", "pu1");
|
||||
persistenceUnits.put("Person", "pu2");
|
||||
ExpectedLookupTemplate jt = new ExpectedLookupTemplate();
|
||||
jt.addObject("java:comp/env/pu1", mockEmf);
|
||||
jt.addObject("java:comp/env/pu2", mockEmf2);
|
||||
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
PersistenceAnnotationBeanPostProcessor bpp = new PersistenceAnnotationBeanPostProcessor();
|
||||
bpp.setPersistenceUnits(persistenceUnits);
|
||||
bpp.setDefaultPersistenceUnitName("System");
|
||||
bpp.setJndiTemplate(jt);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
bf.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class));
|
||||
bf.registerBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class));
|
||||
|
||||
DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter)
|
||||
bf.getBean(DefaultPublicPersistenceUnitSetter.class.getName());
|
||||
DefaultPublicPersistenceUnitSetterNamedPerson bean2 = (DefaultPublicPersistenceUnitSetterNamedPerson)
|
||||
bf.getBean(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName());
|
||||
assertSame(mockEmf, bean.emf);
|
||||
assertSame(mockEmf2, bean2.emf);
|
||||
}
|
||||
|
||||
public void testSinglePersistenceUnitFromJndi() {
|
||||
Map<String, String> persistenceUnits = new HashMap<String, String>();
|
||||
persistenceUnits.put("Person", "pu1");
|
||||
ExpectedLookupTemplate jt = new ExpectedLookupTemplate();
|
||||
jt.addObject("java:comp/env/pu1", mockEmf);
|
||||
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
PersistenceAnnotationBeanPostProcessor bpp = new PersistenceAnnotationBeanPostProcessor();
|
||||
bpp.setPersistenceUnits(persistenceUnits);
|
||||
bpp.setJndiTemplate(jt);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
bf.registerBeanDefinition(DefaultPublicPersistenceUnitSetter.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceUnitSetter.class));
|
||||
bf.registerBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceUnitSetterNamedPerson.class));
|
||||
|
||||
DefaultPublicPersistenceUnitSetter bean = (DefaultPublicPersistenceUnitSetter)
|
||||
bf.getBean(DefaultPublicPersistenceUnitSetter.class.getName());
|
||||
DefaultPublicPersistenceUnitSetterNamedPerson bean2 = (DefaultPublicPersistenceUnitSetterNamedPerson)
|
||||
bf.getBean(DefaultPublicPersistenceUnitSetterNamedPerson.class.getName());
|
||||
assertSame(mockEmf, bean.emf);
|
||||
assertSame(mockEmf, bean2.emf);
|
||||
}
|
||||
|
||||
public void testPersistenceContextsFromJndi() {
|
||||
Object mockEm = (EntityManager) MockControl.createControl(EntityManager.class).getMock();
|
||||
Object mockEm2 = (EntityManager) MockControl.createControl(EntityManager.class).getMock();
|
||||
Object mockEm3 = (EntityManager) MockControl.createControl(EntityManager.class).getMock();
|
||||
|
||||
Map<String, String> persistenceContexts = new HashMap<String, String>();
|
||||
persistenceContexts.put("", "pc1");
|
||||
persistenceContexts.put("Person", "pc2");
|
||||
Map<String, String> extendedPersistenceContexts = new HashMap<String, String>();
|
||||
extendedPersistenceContexts .put("", "pc3");
|
||||
ExpectedLookupTemplate jt = new ExpectedLookupTemplate();
|
||||
jt.addObject("java:comp/env/pc1", mockEm);
|
||||
jt.addObject("java:comp/env/pc2", mockEm2);
|
||||
jt.addObject("java:comp/env/pc3", mockEm3);
|
||||
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
PersistenceAnnotationBeanPostProcessor bpp = new PersistenceAnnotationBeanPostProcessor();
|
||||
bpp.setPersistenceContexts(persistenceContexts);
|
||||
bpp.setExtendedPersistenceContexts(extendedPersistenceContexts);
|
||||
bpp.setJndiTemplate(jt);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
bf.registerBeanDefinition(DefaultPrivatePersistenceContextField.class.getName(),
|
||||
new RootBeanDefinition(DefaultPrivatePersistenceContextField.class));
|
||||
bf.registerBeanDefinition(DefaultPrivatePersistenceContextFieldNamedPerson.class.getName(),
|
||||
new RootBeanDefinition(DefaultPrivatePersistenceContextFieldNamedPerson.class));
|
||||
bf.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class));
|
||||
|
||||
DefaultPrivatePersistenceContextField bean1 = (DefaultPrivatePersistenceContextField)
|
||||
bf.getBean(DefaultPrivatePersistenceContextField.class.getName());
|
||||
DefaultPrivatePersistenceContextFieldNamedPerson bean2 = (DefaultPrivatePersistenceContextFieldNamedPerson)
|
||||
bf.getBean(DefaultPrivatePersistenceContextFieldNamedPerson.class.getName());
|
||||
DefaultPublicPersistenceContextSetter bean3 = (DefaultPublicPersistenceContextSetter)
|
||||
bf.getBean(DefaultPublicPersistenceContextSetter.class.getName());
|
||||
assertSame(mockEm, bean1.em);
|
||||
assertSame(mockEm2, bean2.em);
|
||||
assertSame(mockEm3, bean3.em);
|
||||
}
|
||||
|
||||
public void testPersistenceContextsFromJndiWithDefaultUnit() {
|
||||
Object mockEm = (EntityManager) MockControl.createControl(EntityManager.class).getMock();
|
||||
Object mockEm2 = (EntityManager) MockControl.createControl(EntityManager.class).getMock();
|
||||
Object mockEm3 = (EntityManager) MockControl.createControl(EntityManager.class).getMock();
|
||||
|
||||
Map<String, String> persistenceContexts = new HashMap<String, String>();
|
||||
persistenceContexts.put("System", "pc1");
|
||||
persistenceContexts.put("Person", "pc2");
|
||||
Map<String, String> extendedPersistenceContexts = new HashMap<String, String>();
|
||||
extendedPersistenceContexts .put("System", "pc3");
|
||||
ExpectedLookupTemplate jt = new ExpectedLookupTemplate();
|
||||
jt.addObject("java:comp/env/pc1", mockEm);
|
||||
jt.addObject("java:comp/env/pc2", mockEm2);
|
||||
jt.addObject("java:comp/env/pc3", mockEm3);
|
||||
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
PersistenceAnnotationBeanPostProcessor bpp = new PersistenceAnnotationBeanPostProcessor();
|
||||
bpp.setPersistenceContexts(persistenceContexts);
|
||||
bpp.setExtendedPersistenceContexts(extendedPersistenceContexts);
|
||||
bpp.setDefaultPersistenceUnitName("System");
|
||||
bpp.setJndiTemplate(jt);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
bf.registerBeanDefinition(DefaultPrivatePersistenceContextField.class.getName(),
|
||||
new RootBeanDefinition(DefaultPrivatePersistenceContextField.class));
|
||||
bf.registerBeanDefinition(DefaultPrivatePersistenceContextFieldNamedPerson.class.getName(),
|
||||
new RootBeanDefinition(DefaultPrivatePersistenceContextFieldNamedPerson.class));
|
||||
bf.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class));
|
||||
|
||||
DefaultPrivatePersistenceContextField bean1 = (DefaultPrivatePersistenceContextField)
|
||||
bf.getBean(DefaultPrivatePersistenceContextField.class.getName());
|
||||
DefaultPrivatePersistenceContextFieldNamedPerson bean2 = (DefaultPrivatePersistenceContextFieldNamedPerson)
|
||||
bf.getBean(DefaultPrivatePersistenceContextFieldNamedPerson.class.getName());
|
||||
DefaultPublicPersistenceContextSetter bean3 = (DefaultPublicPersistenceContextSetter)
|
||||
bf.getBean(DefaultPublicPersistenceContextSetter.class.getName());
|
||||
assertSame(mockEm, bean1.em);
|
||||
assertSame(mockEm2, bean2.em);
|
||||
assertSame(mockEm3, bean3.em);
|
||||
}
|
||||
|
||||
public void testSinglePersistenceContextFromJndi() {
|
||||
Object mockEm = (EntityManager) MockControl.createControl(EntityManager.class).getMock();
|
||||
Object mockEm2 = (EntityManager) MockControl.createControl(EntityManager.class).getMock();
|
||||
|
||||
Map<String, String> persistenceContexts = new HashMap<String, String>();
|
||||
persistenceContexts.put("System", "pc1");
|
||||
Map<String, String> extendedPersistenceContexts = new HashMap<String, String>();
|
||||
extendedPersistenceContexts .put("System", "pc2");
|
||||
ExpectedLookupTemplate jt = new ExpectedLookupTemplate();
|
||||
jt.addObject("java:comp/env/pc1", mockEm);
|
||||
jt.addObject("java:comp/env/pc2", mockEm2);
|
||||
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
PersistenceAnnotationBeanPostProcessor bpp = new PersistenceAnnotationBeanPostProcessor();
|
||||
bpp.setPersistenceContexts(persistenceContexts);
|
||||
bpp.setExtendedPersistenceContexts(extendedPersistenceContexts);
|
||||
bpp.setJndiTemplate(jt);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
bf.registerBeanDefinition(DefaultPrivatePersistenceContextField.class.getName(),
|
||||
new RootBeanDefinition(DefaultPrivatePersistenceContextField.class));
|
||||
bf.registerBeanDefinition(DefaultPublicPersistenceContextSetter.class.getName(),
|
||||
new RootBeanDefinition(DefaultPublicPersistenceContextSetter.class));
|
||||
|
||||
DefaultPrivatePersistenceContextField bean1 = (DefaultPrivatePersistenceContextField)
|
||||
bf.getBean(DefaultPrivatePersistenceContextField.class.getName());
|
||||
DefaultPublicPersistenceContextSetter bean2 = (DefaultPublicPersistenceContextSetter)
|
||||
bf.getBean(DefaultPublicPersistenceContextSetter.class.getName());
|
||||
assertSame(mockEm, bean1.em);
|
||||
assertSame(mockEm2, bean2.em);
|
||||
}
|
||||
|
||||
public void testFieldOfWrongTypeAnnotatedWithPersistenceUnit() {
|
||||
PersistenceAnnotationBeanPostProcessor babpp = new PersistenceAnnotationBeanPostProcessor();
|
||||
try {
|
||||
babpp.postProcessAfterInstantiation(new FieldOfWrongTypeAnnotatedWithPersistenceUnit(),
|
||||
"bean name does not matter");
|
||||
fail("Can't inject this field");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
// Ok
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetterOfWrongTypeAnnotatedWithPersistenceUnit() {
|
||||
PersistenceAnnotationBeanPostProcessor babpp = new PersistenceAnnotationBeanPostProcessor();
|
||||
try {
|
||||
babpp.postProcessAfterInstantiation(new SetterOfWrongTypeAnnotatedWithPersistenceUnit(),
|
||||
"bean name does not matter");
|
||||
fail("Can't inject this setter");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
// Ok
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetterWithNoArgs() {
|
||||
PersistenceAnnotationBeanPostProcessor babpp = new PersistenceAnnotationBeanPostProcessor();
|
||||
try {
|
||||
babpp.postProcessAfterInstantiation(new SetterWithNoArgs(), "bean name does not matter");
|
||||
fail("Can't inject this setter");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
// Ok
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore
|
||||
public void ignoreTestNoPropertiesPassedIn() {
|
||||
mockEmf.createEntityManager();
|
||||
emfMc.setReturnValue(MockControl.createControl(EntityManager.class).getMock(), 1);
|
||||
emfMc.replay();
|
||||
|
||||
PersistenceAnnotationBeanPostProcessor babpp = new MockPersistenceAnnotationBeanPostProcessor();
|
||||
DefaultPrivatePersistenceContextFieldExtended dppcf = new DefaultPrivatePersistenceContextFieldExtended();
|
||||
babpp.postProcessAfterInstantiation(dppcf, "bean name does not matter");
|
||||
assertNotNull(dppcf.em);
|
||||
emfMc.verify();
|
||||
}
|
||||
|
||||
@Ignore
|
||||
public void ignoreTestPropertiesPassedIn() {
|
||||
Properties props = new Properties();
|
||||
props.put("foo", "bar");
|
||||
mockEmf.createEntityManager(props);
|
||||
emfMc.setReturnValue(MockControl.createControl(EntityManager.class).getMock(), 1);
|
||||
emfMc.replay();
|
||||
|
||||
PersistenceAnnotationBeanPostProcessor babpp = new MockPersistenceAnnotationBeanPostProcessor();
|
||||
DefaultPrivatePersistenceContextFieldExtendedWithProps dppcf =
|
||||
new DefaultPrivatePersistenceContextFieldExtendedWithProps();
|
||||
babpp.postProcessAfterInstantiation(dppcf, "bean name does not matter");
|
||||
assertNotNull(dppcf.em);
|
||||
emfMc.verify();
|
||||
}
|
||||
|
||||
public void testPropertiesForTransactionalEntityManager() {
|
||||
Properties props = new Properties();
|
||||
props.put("foo", "bar");
|
||||
MockControl emC = MockControl.createControl(EntityManager.class);
|
||||
EntityManager em = (EntityManager) emC.getMock();
|
||||
emfMc.expectAndReturn(mockEmf.createEntityManager(props), em);
|
||||
emC.expectAndReturn(em.getDelegate(), new Object());
|
||||
em.close();
|
||||
|
||||
emfMc.replay();
|
||||
emC.replay();
|
||||
|
||||
PersistenceAnnotationBeanPostProcessor babpp = new MockPersistenceAnnotationBeanPostProcessor();
|
||||
DefaultPrivatePersistenceContextFieldWithProperties transactionalField =
|
||||
new DefaultPrivatePersistenceContextFieldWithProperties();
|
||||
babpp.postProcessAfterInstantiation(transactionalField, "bean name does not matter");
|
||||
|
||||
assertNotNull(transactionalField.em);
|
||||
assertNotNull(transactionalField.em.getDelegate());
|
||||
|
||||
emfMc.verify();
|
||||
emC.verify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds an EMF to the thread and tests if EM with different properties
|
||||
* generate new EMs or not.
|
||||
*/
|
||||
public void testPropertiesForSharedEntityManager1() {
|
||||
Properties props = new Properties();
|
||||
props.put("foo", "bar");
|
||||
MockControl emC = MockControl.createControl(EntityManager.class);
|
||||
EntityManager em = (EntityManager) emC.getMock();
|
||||
// only one call made - the first EM definition wins (in this case the one w/ the properties)
|
||||
emfMc.expectAndReturn(mockEmf.createEntityManager(props), em);
|
||||
emC.expectAndReturn(em.getDelegate(), new Object(), 2);
|
||||
em.close();
|
||||
|
||||
emfMc.replay();
|
||||
emC.replay();
|
||||
|
||||
PersistenceAnnotationBeanPostProcessor babpp = new MockPersistenceAnnotationBeanPostProcessor();
|
||||
DefaultPrivatePersistenceContextFieldWithProperties transactionalFieldWithProperties =
|
||||
new DefaultPrivatePersistenceContextFieldWithProperties();
|
||||
DefaultPrivatePersistenceContextField transactionalField = new DefaultPrivatePersistenceContextField();
|
||||
|
||||
babpp.postProcessAfterInstantiation(transactionalFieldWithProperties, "bean name does not matter");
|
||||
babpp.postProcessAfterInstantiation(transactionalField, "bean name does not matter");
|
||||
|
||||
assertNotNull(transactionalFieldWithProperties.em);
|
||||
assertNotNull(transactionalField.em);
|
||||
// the EM w/ properties will be created
|
||||
assertNotNull(transactionalFieldWithProperties.em.getDelegate());
|
||||
// bind em to the thread now since it's created
|
||||
try {
|
||||
TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(em));
|
||||
assertNotNull(transactionalField.em.getDelegate());
|
||||
emfMc.verify();
|
||||
emC.verify();
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.unbindResource(mockEmf);
|
||||
}
|
||||
}
|
||||
|
||||
public void testPropertiesForSharedEntityManager2() {
|
||||
Properties props = new Properties();
|
||||
props.put("foo", "bar");
|
||||
MockControl emC = MockControl.createControl(EntityManager.class);
|
||||
EntityManager em = (EntityManager) emC.getMock();
|
||||
// only one call made - the first EM definition wins (in this case the one w/o the properties)
|
||||
emfMc.expectAndReturn(mockEmf.createEntityManager(), em);
|
||||
emC.expectAndReturn(em.getDelegate(), new Object(), 2);
|
||||
em.close();
|
||||
|
||||
emfMc.replay();
|
||||
emC.replay();
|
||||
|
||||
PersistenceAnnotationBeanPostProcessor babpp = new MockPersistenceAnnotationBeanPostProcessor();
|
||||
DefaultPrivatePersistenceContextFieldWithProperties transactionalFieldWithProperties =
|
||||
new DefaultPrivatePersistenceContextFieldWithProperties();
|
||||
DefaultPrivatePersistenceContextField transactionalField = new DefaultPrivatePersistenceContextField();
|
||||
|
||||
babpp.postProcessAfterInstantiation(transactionalFieldWithProperties, "bean name does not matter");
|
||||
babpp.postProcessAfterInstantiation(transactionalField, "bean name does not matter");
|
||||
|
||||
assertNotNull(transactionalFieldWithProperties.em);
|
||||
assertNotNull(transactionalField.em);
|
||||
// the EM w/o properties will be created
|
||||
assertNotNull(transactionalField.em.getDelegate());
|
||||
// bind em to the thread now since it's created
|
||||
try {
|
||||
TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(em));
|
||||
assertNotNull(transactionalFieldWithProperties.em.getDelegate());
|
||||
emfMc.verify();
|
||||
emC.verify();
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.unbindResource(mockEmf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class MockPersistenceAnnotationBeanPostProcessor extends PersistenceAnnotationBeanPostProcessor {
|
||||
|
||||
@Override
|
||||
protected EntityManagerFactory findEntityManagerFactory(String emfName, String requestingBeanName) {
|
||||
return mockEmf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class DefaultPrivatePersistenceContextField {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
}
|
||||
|
||||
|
||||
public static class DefaultVendorSpecificPrivatePersistenceContextField {
|
||||
|
||||
@PersistenceContext
|
||||
private HibernateEntityManager em;
|
||||
}
|
||||
|
||||
|
||||
public static class FactoryBeanWithPersistenceContextField implements FactoryBean {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager em;
|
||||
|
||||
public Object getObject() throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Class getObjectType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class DefaultPrivatePersistenceContextFieldNamedPerson {
|
||||
|
||||
@PersistenceContext(unitName = "Person")
|
||||
private EntityManager em;
|
||||
}
|
||||
|
||||
|
||||
public static class DefaultPrivatePersistenceContextFieldWithProperties {
|
||||
|
||||
@PersistenceContext(properties = { @PersistenceProperty(name = "foo", value = "bar") })
|
||||
private EntityManager em;
|
||||
}
|
||||
|
||||
|
||||
@Repository
|
||||
public static class DefaultPublicPersistenceContextSetter implements Serializable {
|
||||
|
||||
private EntityManager em;
|
||||
|
||||
@PersistenceContext(type = PersistenceContextType.EXTENDED)
|
||||
public void setEntityManager(EntityManager em) {
|
||||
if (this.em != null) {
|
||||
throw new IllegalStateException("Already called");
|
||||
}
|
||||
this.em = em;
|
||||
}
|
||||
|
||||
public EntityManager getEntityManager() {
|
||||
return em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class DefaultPrivatePersistenceUnitField {
|
||||
|
||||
@PersistenceUnit
|
||||
private EntityManagerFactory emf;
|
||||
}
|
||||
|
||||
|
||||
public static class DefaultPublicPersistenceUnitSetter {
|
||||
|
||||
private EntityManagerFactory emf;
|
||||
|
||||
@PersistenceUnit
|
||||
public void setEmf(EntityManagerFactory emf) {
|
||||
if (this.emf != null) {
|
||||
throw new IllegalStateException("Already called");
|
||||
}
|
||||
this.emf = emf;
|
||||
}
|
||||
|
||||
public EntityManagerFactory getEmf() {
|
||||
return emf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Repository
|
||||
public static class DefaultPublicPersistenceUnitSetterNamedPerson {
|
||||
|
||||
private EntityManagerFactory emf;
|
||||
|
||||
@PersistenceUnit(unitName = "Person")
|
||||
public void setEmf(EntityManagerFactory emf) {
|
||||
this.emf = emf;
|
||||
}
|
||||
|
||||
public EntityManagerFactory getEntityManagerFactory() {
|
||||
return emf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class FieldOfWrongTypeAnnotatedWithPersistenceUnit {
|
||||
|
||||
@PersistenceUnit
|
||||
public String thisFieldIsOfTheWrongType;
|
||||
}
|
||||
|
||||
|
||||
public static class SetterOfWrongTypeAnnotatedWithPersistenceUnit {
|
||||
|
||||
@PersistenceUnit
|
||||
public void setSomething(Comparable c) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class SetterWithNoArgs {
|
||||
|
||||
@PersistenceUnit
|
||||
public void setSomething() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class DefaultPrivatePersistenceContextFieldExtended {
|
||||
|
||||
@PersistenceContext(type = PersistenceContextType.EXTENDED)
|
||||
private EntityManager em;
|
||||
}
|
||||
|
||||
|
||||
public static class DefaultPrivatePersistenceContextFieldExtendedWithProps {
|
||||
|
||||
@PersistenceContext(type = PersistenceContextType.EXTENDED, properties = { @PersistenceProperty(name = "foo", value = "bar") })
|
||||
private EntityManager em;
|
||||
}
|
||||
|
||||
|
||||
private interface EntityManagerFactoryWithInfo extends EntityManagerFactory, EntityManagerFactoryInfo {
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static class DummyInvocationHandler implements InvocationHandler, Serializable {
|
||||
|
||||
public static boolean closed;
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
if ("close".equals(method.getName())) {
|
||||
closed = true;
|
||||
return null;
|
||||
}
|
||||
if ("toString".equals(method.getName())) {
|
||||
return "";
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.support;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.junit.Test;
|
||||
import org.springframework.orm.jpa.EntityManagerHolder;
|
||||
import org.springframework.orm.jpa.EntityManagerProxy;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class SharedEntityManagerFactoryTests {
|
||||
|
||||
@Test
|
||||
public void testValidUsage() {
|
||||
Object o = new Object();
|
||||
|
||||
MockControl emMc = MockControl.createControl(EntityManager.class);
|
||||
EntityManager mockEm = (EntityManager) emMc.getMock();
|
||||
|
||||
mockEm.contains(o);
|
||||
emMc.setReturnValue(false, 1);
|
||||
|
||||
mockEm.close();
|
||||
emMc.setVoidCallable(1);
|
||||
emMc.replay();
|
||||
|
||||
MockControl emfMc = MockControl.createControl(EntityManagerFactory.class);
|
||||
EntityManagerFactory mockEmf = (EntityManagerFactory) emfMc.getMock();
|
||||
mockEmf.createEntityManager();
|
||||
emfMc.setReturnValue(mockEm, 1);
|
||||
emfMc.replay();
|
||||
|
||||
SharedEntityManagerBean proxyFactoryBean = new SharedEntityManagerBean();
|
||||
proxyFactoryBean.setEntityManagerFactory(mockEmf);
|
||||
proxyFactoryBean.afterPropertiesSet();
|
||||
|
||||
assertTrue(EntityManager.class.isAssignableFrom(proxyFactoryBean.getObjectType()));
|
||||
assertTrue(proxyFactoryBean.isSingleton());
|
||||
|
||||
EntityManager proxy = (EntityManager) proxyFactoryBean.getObject();
|
||||
assertSame(proxy, proxyFactoryBean.getObject());
|
||||
assertFalse(proxy.contains(o));
|
||||
|
||||
assertTrue(proxy instanceof EntityManagerProxy);
|
||||
EntityManagerProxy emProxy = (EntityManagerProxy) proxy;
|
||||
try {
|
||||
emProxy.getTargetEntityManager();
|
||||
fail("Should have thrown IllegalStateException outside of transaction");
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
// expected
|
||||
}
|
||||
|
||||
TransactionSynchronizationManager.bindResource(mockEmf, new EntityManagerHolder(mockEm));
|
||||
try {
|
||||
assertSame(mockEm, emProxy.getTargetEntityManager());
|
||||
}
|
||||
finally {
|
||||
TransactionSynchronizationManager.unbindResource(mockEmf);
|
||||
}
|
||||
|
||||
emfMc.verify();
|
||||
emMc.verify();
|
||||
|
||||
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.toplink;
|
||||
|
||||
import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests;
|
||||
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
|
||||
|
||||
/**
|
||||
* TopLink-specific JPA tests.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class TopLinkEntityManagerFactoryIntegrationTests extends AbstractContainerEntityManagerFactoryIntegrationTests {
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return TOPLINK_CONFIG_LOCATIONS;
|
||||
}
|
||||
|
||||
|
||||
public void testCanCastNativeEntityManagerFactoryToTopLinkEntityManagerFactoryImpl() {
|
||||
EntityManagerFactoryInfo emfi = (EntityManagerFactoryInfo) entityManagerFactory;
|
||||
assertTrue(emfi.getNativeEntityManagerFactory().getClass().getName().endsWith("EntityManagerFactoryImpl"));
|
||||
}
|
||||
|
||||
public void testCanCastSharedEntityManagerProxyToTopLinkEntityManager() {
|
||||
assertTrue(sharedEntityManager instanceof oracle.toplink.essentials.ejb.cmp3.EntityManager);
|
||||
oracle.toplink.essentials.ejb.cmp3.EntityManager toplinkEntityManager =
|
||||
(oracle.toplink.essentials.ejb.cmp3.EntityManager) sharedEntityManager;
|
||||
assertNotNull(toplinkEntityManager.getActiveSession());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.orm.jpa.toplink;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import org.springframework.orm.jpa.AbstractContainerEntityManagerFactoryIntegrationTests;
|
||||
|
||||
/**
|
||||
* Toplink-specific JPA tests with multiple EntityManagerFactory instances.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class TopLinkMultiEntityManagerFactoryIntegrationTests extends
|
||||
AbstractContainerEntityManagerFactoryIntegrationTests {
|
||||
|
||||
private EntityManagerFactory entityManagerFactory2;
|
||||
|
||||
|
||||
public TopLinkMultiEntityManagerFactoryIntegrationTests() {
|
||||
setAutowireMode(AUTOWIRE_BY_NAME);
|
||||
}
|
||||
|
||||
public void setEntityManagerFactory2(EntityManagerFactory entityManagerFactory2) {
|
||||
this.entityManagerFactory2 = entityManagerFactory2;
|
||||
}
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return new String[] {
|
||||
"/org/springframework/orm/jpa/toplink/toplink-manager-multi.xml",
|
||||
"/org/springframework/orm/jpa/memdb.xml"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void testEntityManagerFactory2() {
|
||||
EntityManager em = this.entityManagerFactory2.createEntityManager();
|
||||
try {
|
||||
em.createQuery("select tb from TestBean");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// expected
|
||||
}
|
||||
finally {
|
||||
em.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<import resource="classpath:/org/springframework/orm/jpa/multi-jpa-emf.xml"/>
|
||||
|
||||
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter">
|
||||
<property name="database" value="HSQL"/>
|
||||
<property name="showSql" value="true"/>
|
||||
<property name="generateDdl" value="true"/>
|
||||
</bean>
|
||||
|
||||
<bean id="jpaProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
<property name="persistenceXmlLocation" value="org/springframework/orm/jpa/domain/persistence.xml"/>
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="jpaVendorAdapter">
|
||||
<bean class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter">
|
||||
<property name="database" value="HSQL"/>
|
||||
<property name="showSql" value="true"/>
|
||||
<property name="generateDdl" value="true"/>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Convenient superclass for JUnit 3.8 based tests depending on a Spring
|
||||
* context. The test instance itself is populated by Dependency Injection.
|
||||
* </p>
|
||||
* <p>
|
||||
* Really for integration testing, not unit testing. You should <i>not</i>
|
||||
* normally use the Spring container for unit tests: simply populate your POJOs
|
||||
* in plain JUnit tests!
|
||||
* </p>
|
||||
* <p>
|
||||
* This supports two modes of populating the test:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>Via Setter Dependency Injection. Simply express dependencies on objects
|
||||
* in the test fixture, and they will be satisfied by autowiring by type.
|
||||
* <li>Via Field Injection. Declare protected variables of the required type
|
||||
* which match named beans in the context. This is autowire by name, rather than
|
||||
* type. This approach is based on an approach originated by Ara Abrahmian.
|
||||
* Setter Dependency Injection is the default: set the
|
||||
* <code>populateProtectedVariables</code> property to <code>true</code> in
|
||||
* the constructor to switch on Field Injection.
|
||||
* </ul>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
* @author Rick Evans
|
||||
* @author Sam Brannen
|
||||
* @since 1.1.1
|
||||
* @see #setDirty
|
||||
* @see #contextKey
|
||||
* @see #getContext
|
||||
* @see #getConfigLocations
|
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework
|
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractDependencyInjectionSpringContextTests extends AbstractSingleSpringContextTests {
|
||||
|
||||
/**
|
||||
* Constant that indicates no autowiring at all.
|
||||
*
|
||||
* @see #setAutowireMode
|
||||
*/
|
||||
public static final int AUTOWIRE_NO = 0;
|
||||
|
||||
/**
|
||||
* Constant that indicates autowiring bean properties by name.
|
||||
*
|
||||
* @see #setAutowireMode
|
||||
*/
|
||||
public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
|
||||
|
||||
/**
|
||||
* Constant that indicates autowiring bean properties by type.
|
||||
*
|
||||
* @see #setAutowireMode
|
||||
*/
|
||||
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
|
||||
|
||||
private boolean populateProtectedVariables = false;
|
||||
|
||||
private int autowireMode = AUTOWIRE_BY_TYPE;
|
||||
|
||||
private boolean dependencyCheck = true;
|
||||
|
||||
private String[] managedVariableNames;
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor for AbstractDependencyInjectionSpringContextTests.
|
||||
*/
|
||||
public AbstractDependencyInjectionSpringContextTests() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for AbstractDependencyInjectionSpringContextTests with a
|
||||
* JUnit name.
|
||||
* @param name the name of this text fixture
|
||||
*/
|
||||
public AbstractDependencyInjectionSpringContextTests(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether to populate protected variables of this test case. Default is
|
||||
* <code>false</code>.
|
||||
*/
|
||||
public final void setPopulateProtectedVariables(boolean populateFields) {
|
||||
this.populateProtectedVariables = populateFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to populate protected variables of this test case.
|
||||
*/
|
||||
public final boolean isPopulateProtectedVariables() {
|
||||
return this.populateProtectedVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the autowire mode for test properties set by Dependency Injection.
|
||||
* <p>The default is {@link #AUTOWIRE_BY_TYPE}. Can be set to
|
||||
* {@link #AUTOWIRE_BY_NAME} or {@link #AUTOWIRE_NO} instead.
|
||||
* @see #AUTOWIRE_BY_TYPE
|
||||
* @see #AUTOWIRE_BY_NAME
|
||||
* @see #AUTOWIRE_NO
|
||||
*/
|
||||
public final void setAutowireMode(final int autowireMode) {
|
||||
this.autowireMode = autowireMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the autowire mode for test properties set by Dependency Injection.
|
||||
*/
|
||||
public final int getAutowireMode() {
|
||||
return this.autowireMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not dependency checking should be performed for test
|
||||
* properties set by Dependency Injection.
|
||||
* <p>The default is <code>true</code>, meaning that tests cannot be run
|
||||
* unless all properties are populated.
|
||||
*/
|
||||
public final void setDependencyCheck(final boolean dependencyCheck) {
|
||||
this.dependencyCheck = dependencyCheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not dependency checking should be performed for test
|
||||
* properties set by Dependency Injection.
|
||||
*/
|
||||
public final boolean isDependencyCheck() {
|
||||
return this.dependencyCheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare this test instance, injecting dependencies into its protected
|
||||
* fields and its bean properties.
|
||||
* <p>Note: if the {@link ApplicationContext} for this test instance has not
|
||||
* been configured (e.g., is <code>null</code>), dependency injection
|
||||
* will naturally <strong>not</strong> be performed, but an informational
|
||||
* message will be written to the log.
|
||||
* @see #injectDependencies()
|
||||
*/
|
||||
protected void prepareTestInstance() throws Exception {
|
||||
if (getApplicationContext() == null) {
|
||||
if (this.logger.isInfoEnabled()) {
|
||||
this.logger.info("ApplicationContext has not been configured for test [" + getClass().getName()
|
||||
+ "]: dependency injection will NOT be performed.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
injectDependencies();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject dependencies into 'this' instance (that is, this test instance).
|
||||
* <p>The default implementation populates protected variables if the
|
||||
* {@link #populateProtectedVariables() appropriate flag is set}, else uses
|
||||
* autowiring if autowiring is switched on (which it is by default).
|
||||
* <p>Override this method if you need full control over how dependencies are
|
||||
* injected into the test instance.
|
||||
* @throws Exception in case of dependency injection failure
|
||||
* @throws IllegalStateException if the {@link ApplicationContext} for this
|
||||
* test instance has not been configured
|
||||
* @see #populateProtectedVariables()
|
||||
*/
|
||||
protected void injectDependencies() throws Exception {
|
||||
Assert.state(getApplicationContext() != null,
|
||||
"injectDependencies() called without first configuring an ApplicationContext");
|
||||
if (isPopulateProtectedVariables()) {
|
||||
if (this.managedVariableNames == null) {
|
||||
initManagedVariableNames();
|
||||
}
|
||||
populateProtectedVariables();
|
||||
}
|
||||
getApplicationContext().getBeanFactory().autowireBeanProperties(this, getAutowireMode(), isDependencyCheck());
|
||||
}
|
||||
|
||||
private void initManagedVariableNames() throws IllegalAccessException {
|
||||
List managedVarNames = new LinkedList();
|
||||
Class clazz = getClass();
|
||||
do {
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Found " + fields.length + " fields on " + clazz);
|
||||
}
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
field.setAccessible(true);
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Candidate field: " + field);
|
||||
}
|
||||
if (isProtectedInstanceField(field)) {
|
||||
Object oldValue = field.get(this);
|
||||
if (oldValue == null) {
|
||||
managedVarNames.add(field.getName());
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Added managed variable '" + field.getName() + "'");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Rejected managed variable '" + field.getName() + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
clazz = clazz.getSuperclass();
|
||||
} while (!clazz.equals(AbstractDependencyInjectionSpringContextTests.class));
|
||||
|
||||
this.managedVariableNames = (String[]) managedVarNames.toArray(new String[managedVarNames.size()]);
|
||||
}
|
||||
|
||||
private boolean isProtectedInstanceField(Field field) {
|
||||
int modifiers = field.getModifiers();
|
||||
return !Modifier.isStatic(modifiers) && Modifier.isProtected(modifiers);
|
||||
}
|
||||
|
||||
private void populateProtectedVariables() throws IllegalAccessException {
|
||||
for (int i = 0; i < this.managedVariableNames.length; i++) {
|
||||
String varName = this.managedVariableNames[i];
|
||||
Object bean = null;
|
||||
try {
|
||||
Field field = findField(getClass(), varName);
|
||||
bean = getApplicationContext().getBean(varName, field.getType());
|
||||
field.setAccessible(true);
|
||||
field.set(this, bean);
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Populated field: " + field);
|
||||
}
|
||||
}
|
||||
catch (NoSuchFieldException ex) {
|
||||
if (this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("No field with name '" + varName + "'");
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
if (this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("No bean with name '" + varName + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Field findField(Class clazz, String name) throws NoSuchFieldException {
|
||||
try {
|
||||
return clazz.getDeclaredField(name);
|
||||
}
|
||||
catch (NoSuchFieldException ex) {
|
||||
Class superclass = clazz.getSuperclass();
|
||||
if (superclass != AbstractSpringContextTests.class) {
|
||||
return findField(superclass, name);
|
||||
}
|
||||
else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReader;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Abstract JUnit 3.8 test class that holds and exposes a single Spring
|
||||
* {@link org.springframework.context.ApplicationContext ApplicationContext}.
|
||||
* </p>
|
||||
* <p>
|
||||
* This class will cache contexts based on a <i>context key</i>: normally the
|
||||
* config locations String array describing the Spring resource descriptors
|
||||
* making up the context. Unless the {@link #setDirty()} method is called by a
|
||||
* test, the context will not be reloaded, even across different subclasses of
|
||||
* this test. This is particularly beneficial if your context is slow to
|
||||
* construct, for example if you are using Hibernate and the time taken to load
|
||||
* the mappings is an issue.
|
||||
* </p>
|
||||
* <p>
|
||||
* For such standard usage, simply override the {@link #getConfigLocations()}
|
||||
* method and provide the desired config files. For alternative configuration
|
||||
* options, see {@link #getConfigPath()} and {@link #getConfigPaths()}.
|
||||
* </p>
|
||||
* <p>
|
||||
* If you don't want to load a standard context from an array of config
|
||||
* locations, you can override the {@link #contextKey()} method. In conjunction
|
||||
* with this you typically need to override the {@link #loadContext(Object)}
|
||||
* method, which by default loads the locations specified in the
|
||||
* {@link #getConfigLocations()} method.
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>WARNING:</b> When doing integration tests from within Eclipse, only use
|
||||
* classpath resource URLs. Else, you may see misleading failures when changing
|
||||
* context locations.
|
||||
* </p>
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
* @see #getConfigLocations()
|
||||
* @see #contextKey()
|
||||
* @see #loadContext(Object)
|
||||
* @see #getApplicationContext()
|
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework
|
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractSingleSpringContextTests extends AbstractSpringContextTests {
|
||||
|
||||
/** Application context this test will run against */
|
||||
protected ConfigurableApplicationContext applicationContext;
|
||||
|
||||
private int loadCount = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor for AbstractSingleSpringContextTests.
|
||||
*/
|
||||
public AbstractSingleSpringContextTests() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for AbstractSingleSpringContextTests with a JUnit name.
|
||||
* @param name the name of this text fixture
|
||||
*/
|
||||
public AbstractSingleSpringContextTests(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation is final. Override <code>onSetUp</code> for custom behavior.
|
||||
* @see #onSetUp()
|
||||
*/
|
||||
protected final void setUp() throws Exception {
|
||||
// lazy load, in case getApplicationContext() has not yet been called.
|
||||
if (this.applicationContext == null) {
|
||||
this.applicationContext = getContext(contextKey());
|
||||
}
|
||||
prepareTestInstance();
|
||||
onSetUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare this test instance, for example populating its fields.
|
||||
* The context has already been loaded at the time of this callback.
|
||||
* <p>The default implementation does nothing.
|
||||
* @throws Exception in case of preparation failure
|
||||
*/
|
||||
protected void prepareTestInstance() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this method in place of the <code>setUp()</code>
|
||||
* method, which is final in this class.
|
||||
* <p>The default implementation does nothing.
|
||||
* @throws Exception simply let any exception propagate
|
||||
*/
|
||||
protected void onSetUp() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to say that the "applicationContext" instance variable is dirty
|
||||
* and should be reloaded. We need to do this if a test has modified the
|
||||
* context (for example, by replacing a bean definition).
|
||||
*/
|
||||
protected void setDirty() {
|
||||
setDirty(contextKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation is final. Override <code>onTearDown</code> for
|
||||
* custom behavior.
|
||||
* @see #onTearDown()
|
||||
*/
|
||||
protected final void tearDown() throws Exception {
|
||||
onTearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this to add custom behavior on teardown.
|
||||
* @throws Exception simply let any exception propagate
|
||||
*/
|
||||
protected void onTearDown() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a key for this context. Default is the config location array as
|
||||
* determined by {@link #getConfigLocations()}.
|
||||
* <p>If you override this method, you will typically have to override
|
||||
* {@link #loadContext(Object)} as well, being able to handle the key type
|
||||
* that this method returns.
|
||||
* @return the context key
|
||||
* @see #getConfigLocations()
|
||||
*/
|
||||
protected Object contextKey() {
|
||||
return getConfigLocations();
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation assumes a key of type String array and loads a
|
||||
* context from the given locations.
|
||||
* <p>If you override {@link #contextKey()}, you will typically have to
|
||||
* override this method as well, being able to handle the key type that
|
||||
* <code>contextKey()</code> returns.
|
||||
* @see #getConfigLocations()
|
||||
*/
|
||||
protected ConfigurableApplicationContext loadContext(Object key) throws Exception {
|
||||
return loadContextLocations((String[]) key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a Spring ApplicationContext from the given config locations.
|
||||
* <p>The default implementation creates a standard
|
||||
* {@link #createApplicationContext GenericApplicationContext}, allowing
|
||||
* for customizing the internal bean factory through
|
||||
* {@link #customizeBeanFactory}.
|
||||
* @param locations the config locations (as Spring resource locations,
|
||||
* e.g. full classpath locations or any kind of URL)
|
||||
* @return the corresponding ApplicationContext instance (potentially cached)
|
||||
* @throws Exception if context loading failed
|
||||
* @see #createApplicationContext(String[])
|
||||
*/
|
||||
protected ConfigurableApplicationContext loadContextLocations(String[] locations) throws Exception {
|
||||
++this.loadCount;
|
||||
if (this.logger.isInfoEnabled()) {
|
||||
this.logger.info("Loading context for locations: " + StringUtils.arrayToCommaDelimitedString(locations));
|
||||
}
|
||||
return createApplicationContext(locations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Spring {@link ConfigurableApplicationContext} for use by this test.
|
||||
* <p>The default implementation creates a standard {@link GenericApplicationContext}
|
||||
* instance, calls the {@link #prepareApplicationContext} prepareApplicationContext}
|
||||
* method and the {@link #customizeBeanFactory customizeBeanFactory} method to allow
|
||||
* for customizing the context and its DefaultListableBeanFactory, populates the
|
||||
* context from the specified config <code>locations</code> through the configured
|
||||
* {@link #createBeanDefinitionReader(GenericApplicationContext) BeanDefinitionReader},
|
||||
* and finally {@link ConfigurableApplicationContext#refresh() refreshes} the context.
|
||||
* @param locations the config locations (as Spring resource locations,
|
||||
* e.g. full classpath locations or any kind of URL)
|
||||
* @return the GenericApplicationContext instance
|
||||
* @see #loadContextLocations(String[])
|
||||
* @see #customizeBeanFactory(DefaultListableBeanFactory)
|
||||
* @see #createBeanDefinitionReader(GenericApplicationContext)
|
||||
*/
|
||||
protected ConfigurableApplicationContext createApplicationContext(String[] locations) {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
prepareApplicationContext(context);
|
||||
customizeBeanFactory(context.getDefaultListableBeanFactory());
|
||||
createBeanDefinitionReader(context).loadBeanDefinitions(locations);
|
||||
context.refresh();
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the GenericApplicationContext used by this test.
|
||||
* Called before bean definitions are read.
|
||||
* <p>The default implementation is empty. Can be overridden in subclasses to
|
||||
* customize GenericApplicationContext's standard settings.
|
||||
* @param context the context for which the BeanDefinitionReader should be created
|
||||
* @see #createApplicationContext
|
||||
* @see org.springframework.context.support.GenericApplicationContext#setResourceLoader
|
||||
* @see org.springframework.context.support.GenericApplicationContext#setId
|
||||
*/
|
||||
protected void prepareApplicationContext(GenericApplicationContext context) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize the internal bean factory of the ApplicationContext used by
|
||||
* this test. Called before bean definitions are read.
|
||||
* <p>The default implementation is empty. Can be overridden in subclasses to
|
||||
* customize DefaultListableBeanFactory's standard settings.
|
||||
* @param beanFactory the newly created bean factory for this context
|
||||
* @see #loadContextLocations
|
||||
* @see #createApplicationContext
|
||||
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowBeanDefinitionOverriding
|
||||
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowEagerClassLoading
|
||||
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowCircularReferences
|
||||
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping
|
||||
*/
|
||||
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for creating new {@link BeanDefinitionReader}s for
|
||||
* loading bean definitions into the supplied
|
||||
* {@link GenericApplicationContext context}.
|
||||
* <p>The default implementation creates a new {@link XmlBeanDefinitionReader}.
|
||||
* Can be overridden in subclasses to provide a different
|
||||
* BeanDefinitionReader implementation.
|
||||
* @param context the context for which the BeanDefinitionReader should be created
|
||||
* @return a BeanDefinitionReader for the supplied context
|
||||
* @see #createApplicationContext(String[])
|
||||
* @see BeanDefinitionReader
|
||||
* @see XmlBeanDefinitionReader
|
||||
*/
|
||||
protected BeanDefinitionReader createBeanDefinitionReader(GenericApplicationContext context) {
|
||||
return new XmlBeanDefinitionReader(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this method to return the locations of their
|
||||
* config files, unless they override {@link #contextKey()} and
|
||||
* {@link #loadContext(Object)} instead.
|
||||
* <p>A plain path will be treated as class path location, e.g.:
|
||||
* "org/springframework/whatever/foo.xml". Note however that you may prefix
|
||||
* path locations with standard Spring resource prefixes. Therefore, a
|
||||
* config location path prefixed with "classpath:" with behave the same as a
|
||||
* plain path, but a config location such as
|
||||
* "file:/some/path/path/location/appContext.xml" will be treated as a
|
||||
* filesystem location.
|
||||
* <p>The default implementation builds config locations for the config paths
|
||||
* specified through {@link #getConfigPaths()}.
|
||||
* @return an array of config locations
|
||||
* @see #getConfigPaths()
|
||||
* @see org.springframework.core.io.ResourceLoader#getResource(String)
|
||||
*/
|
||||
protected String[] getConfigLocations() {
|
||||
String[] paths = getConfigPaths();
|
||||
String[] locations = new String[paths.length];
|
||||
for (int i = 0; i < paths.length; i++) {
|
||||
String path = paths[i];
|
||||
if (path.startsWith("/")) {
|
||||
locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path;
|
||||
}
|
||||
else {
|
||||
locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX +
|
||||
StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(getClass()) + "/" + path);
|
||||
}
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this method to return paths to their config
|
||||
* files, relative to the concrete test class.
|
||||
* <p>A plain path, e.g. "context.xml", will be loaded as classpath resource
|
||||
* from the same package that the concrete test class is defined in. A path
|
||||
* starting with a slash is treated as fully qualified class path location,
|
||||
* e.g.: "/org/springframework/whatever/foo.xml".
|
||||
* <p>The default implementation builds an array for the config path specified
|
||||
* through {@link #getConfigPath()}.
|
||||
* @return an array of config locations
|
||||
* @see #getConfigPath()
|
||||
* @see java.lang.Class#getResource(String)
|
||||
*/
|
||||
protected String[] getConfigPaths() {
|
||||
String path = getConfigPath();
|
||||
return (path != null ? new String[] { path } : new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this method to return a single path to a config
|
||||
* file, relative to the concrete test class.
|
||||
* <p>A plain path, e.g. "context.xml", will be loaded as classpath resource
|
||||
* from the same package that the concrete test class is defined in. A path
|
||||
* starting with a slash is treated as fully qualified class path location,
|
||||
* e.g.: "/org/springframework/whatever/foo.xml".
|
||||
* <p>The default implementation simply returns <code>null</code>.
|
||||
* @return an array of config locations
|
||||
* @see #getConfigPath()
|
||||
* @see java.lang.Class#getResource(String)
|
||||
*/
|
||||
protected String getConfigPath() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ApplicationContext that this base class manages; may be
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public final ConfigurableApplicationContext getApplicationContext() {
|
||||
// lazy load, in case setUp() has not yet been called.
|
||||
if (this.applicationContext == null) {
|
||||
try {
|
||||
this.applicationContext = getContext(contextKey());
|
||||
}
|
||||
catch (Exception e) {
|
||||
// log and continue...
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Caught exception while retrieving the ApplicationContext for test [" +
|
||||
getClass().getName() + "." + getName() + "].", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current number of context load attempts.
|
||||
*/
|
||||
public final int getLoadCount() {
|
||||
return this.loadCount;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Superclass for JUnit 3.8 test cases using Spring
|
||||
* {@link org.springframework.context.ApplicationContext ApplicationContexts}.
|
||||
* </p>
|
||||
* <p>
|
||||
* Maintains a static cache of contexts by key. This has significant performance
|
||||
* benefit if initializing the context would take time. While initializing a
|
||||
* Spring context itself is very quick, some beans in a context, such as a
|
||||
* LocalSessionFactoryBean for working with Hibernate, may take some time to
|
||||
* initialize. Hence it often makes sense to do that initializing once.
|
||||
* </p>
|
||||
* <p>
|
||||
* Any ApplicationContext created by this class will be asked to register a JVM
|
||||
* shutdown hook for itself. Unless the context gets closed early, all context
|
||||
* instances will be automatically closed on JVM shutdown. This allows for
|
||||
* freeing external resources held by beans within the context, e.g. temporary
|
||||
* files.
|
||||
* </p>
|
||||
* <p>
|
||||
* Normally you won't extend this class directly but rather one of its
|
||||
* subclasses.
|
||||
* </p>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 1.1.1
|
||||
* @see AbstractSingleSpringContextTests
|
||||
* @see AbstractDependencyInjectionSpringContextTests
|
||||
* @see AbstractTransactionalSpringContextTests
|
||||
* @see AbstractTransactionalDataSourceSpringContextTests
|
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework
|
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractSpringContextTests extends ConditionalTestCase {
|
||||
|
||||
/**
|
||||
* Map of context keys returned by subclasses of this class, to Spring
|
||||
* contexts. This needs to be static, as JUnit tests are destroyed and
|
||||
* recreated between running individual test methods.
|
||||
*/
|
||||
private static Map<String, ConfigurableApplicationContext> contextKeyToContextMap =
|
||||
new HashMap<String, ConfigurableApplicationContext>();
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor for AbstractSpringContextTests.
|
||||
*/
|
||||
public AbstractSpringContextTests() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for AbstractSpringContextTests with a JUnit name.
|
||||
*/
|
||||
public AbstractSpringContextTests(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Explicitly add an ApplicationContext instance under a given key.
|
||||
* <p>This is not meant to be used by subclasses. It is rather exposed for
|
||||
* special test suite environments.
|
||||
* @param key the context key
|
||||
* @param context the ApplicationContext instance
|
||||
*/
|
||||
public final void addContext(Object key, ConfigurableApplicationContext context) {
|
||||
Assert.notNull(context, "ApplicationContext must not be null");
|
||||
contextKeyToContextMap.put(contextKeyString(key), context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether there is a cached context for the given key.
|
||||
* @param key the context key
|
||||
*/
|
||||
protected final boolean hasCachedContext(Object key) {
|
||||
return contextKeyToContextMap.containsKey(contextKeyString(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the supplied context <code>key</code> is <em>empty</em>.
|
||||
* <p>By default, <code>null</code> values, empty strings, and zero-length
|
||||
* arrays are considered <em>empty</em>.
|
||||
* @param key the context key to check
|
||||
* @return <code>true</code> if the supplied context key is empty
|
||||
*/
|
||||
protected boolean isContextKeyEmpty(Object key) {
|
||||
return (key == null) || ((key instanceof String) && !StringUtils.hasText((String) key)) ||
|
||||
((key instanceof Object[]) && ObjectUtils.isEmpty((Object[]) key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain an ApplicationContext for the given key, potentially cached.
|
||||
* @param key the context key; may be <code>null</code>.
|
||||
* @return the corresponding ApplicationContext instance (potentially cached),
|
||||
* or <code>null</code> if the provided <code>key</code> is <em>empty</em>
|
||||
*/
|
||||
protected final ConfigurableApplicationContext getContext(Object key) throws Exception {
|
||||
if (isContextKeyEmpty(key)) {
|
||||
return null;
|
||||
}
|
||||
String keyString = contextKeyString(key);
|
||||
ConfigurableApplicationContext ctx = contextKeyToContextMap.get(keyString);
|
||||
if (ctx == null) {
|
||||
ctx = loadContext(key);
|
||||
ctx.registerShutdownHook();
|
||||
contextKeyToContextMap.put(keyString, ctx);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the context with the given key as dirty. This will cause the cached
|
||||
* context to be reloaded before the next test case is executed.
|
||||
* <p>Call this method only if you change the state of a singleton bean,
|
||||
* potentially affecting future tests.
|
||||
*/
|
||||
protected final void setDirty(Object contextKey) {
|
||||
String keyString = contextKeyString(contextKey);
|
||||
ConfigurableApplicationContext ctx = contextKeyToContextMap.remove(keyString);
|
||||
if (ctx != null) {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this to return a String representation of their
|
||||
* context key for use in caching and logging.
|
||||
* @param contextKey the context key
|
||||
*/
|
||||
protected String contextKeyString(Object contextKey) {
|
||||
return ObjectUtils.nullSafeToString(contextKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a new ApplicationContext for the given key.
|
||||
* <p>To be implemented by subclasses.
|
||||
* @param key the context key
|
||||
* @return the corresponding ApplicationContext instance (new)
|
||||
*/
|
||||
protected abstract ConfigurableApplicationContext loadContext(Object key) throws Exception;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.LineNumberReader;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.core.io.support.EncodedResource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.test.jdbc.JdbcTestUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Subclass of AbstractTransactionalSpringContextTests that adds some convenience
|
||||
* functionality for JDBC access. Expects a {@link javax.sql.DataSource} bean
|
||||
* to be defined in the Spring application context.
|
||||
*
|
||||
* <p>This class exposes a {@link org.springframework.jdbc.core.JdbcTemplate}
|
||||
* and provides an easy way to delete from the database in a new transaction.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Thomas Risberg
|
||||
* @since 1.1.1
|
||||
* @see #setDataSource(javax.sql.DataSource)
|
||||
* @see #getJdbcTemplate()
|
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework
|
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractTransactionalDataSourceSpringContextTests
|
||||
extends AbstractTransactionalSpringContextTests {
|
||||
|
||||
protected JdbcTemplate jdbcTemplate;
|
||||
|
||||
private String sqlScriptEncoding;
|
||||
|
||||
/**
|
||||
* Did this test delete any tables? If so, we forbid transaction completion,
|
||||
* and only allow rollback.
|
||||
*/
|
||||
private boolean zappedTables;
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor for AbstractTransactionalDataSourceSpringContextTests.
|
||||
*/
|
||||
public AbstractTransactionalDataSourceSpringContextTests() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for AbstractTransactionalDataSourceSpringContextTests with a JUnit name.
|
||||
*/
|
||||
public AbstractTransactionalDataSourceSpringContextTests(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter: DataSource is provided by Dependency Injection.
|
||||
*/
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JdbcTemplate that this base class manages.
|
||||
*/
|
||||
public final JdbcTemplate getJdbcTemplate() {
|
||||
return this.jdbcTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the encoding for SQL scripts, if different from the platform encoding.
|
||||
* @see #executeSqlScript
|
||||
*/
|
||||
public void setSqlScriptEncoding(String sqlScriptEncoding) {
|
||||
this.sqlScriptEncoding = sqlScriptEncoding;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convenient method to delete all rows from these tables.
|
||||
* Calling this method will make avoidance of rollback by calling
|
||||
* <code>setComplete()</code> impossible.
|
||||
* @see #setComplete
|
||||
*/
|
||||
protected void deleteFromTables(String[] names) {
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
int rowCount = this.jdbcTemplate.update("DELETE FROM " + names[i]);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Deleted " + rowCount + " rows from table " + names[i]);
|
||||
}
|
||||
}
|
||||
this.zappedTables = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to prevent the transaction committing if a number of tables have been
|
||||
* cleared, as a defensive measure against accidental <i>permanent</i> wiping of a database.
|
||||
* @see org.springframework.test.AbstractTransactionalSpringContextTests#setComplete()
|
||||
*/
|
||||
protected final void setComplete() {
|
||||
if (this.zappedTables) {
|
||||
throw new IllegalStateException("Cannot set complete after deleting tables");
|
||||
}
|
||||
super.setComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the rows in the given table
|
||||
* @param tableName table name to count rows in
|
||||
* @return the number of rows in the table
|
||||
*/
|
||||
protected int countRowsInTable(String tableName) {
|
||||
return this.jdbcTemplate.queryForInt("SELECT COUNT(0) FROM " + tableName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute the given SQL script. Will be rolled back by default,
|
||||
* according to the fate of the current transaction.
|
||||
* @param sqlResourcePath Spring resource path for the SQL script.
|
||||
* Should normally be loaded by classpath.
|
||||
* <p>Statements should be delimited with a semicolon. If statements are not delimited with
|
||||
* a semicolon then there should be one statement per line. Statements are allowed to span
|
||||
* lines only if they are delimited with a semicolon.
|
||||
* <p><b>Do not use this method to execute DDL if you expect rollback.</b>
|
||||
* @param continueOnError whether or not to continue without throwing
|
||||
* an exception in the event of an error
|
||||
* @throws DataAccessException if there is an error executing a statement
|
||||
* and continueOnError was false
|
||||
*/
|
||||
protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Executing SQL script '" + sqlResourcePath + "'");
|
||||
}
|
||||
|
||||
EncodedResource resource =
|
||||
new EncodedResource(getApplicationContext().getResource(sqlResourcePath), this.sqlScriptEncoding);
|
||||
long startTime = System.currentTimeMillis();
|
||||
List statements = new LinkedList();
|
||||
try {
|
||||
LineNumberReader lnr = new LineNumberReader(resource.getReader());
|
||||
String script = JdbcTestUtils.readScript(lnr);
|
||||
char delimiter = ';';
|
||||
if (!JdbcTestUtils.containsSqlScriptDelimiters(script, delimiter)) {
|
||||
delimiter = '\n';
|
||||
}
|
||||
JdbcTestUtils.splitSqlScript(script, delimiter, statements);
|
||||
for (Iterator itr = statements.iterator(); itr.hasNext(); ) {
|
||||
String statement = (String) itr.next();
|
||||
try {
|
||||
int rowsAffected = this.jdbcTemplate.update(statement);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(rowsAffected + " rows affected by SQL: " + statement);
|
||||
}
|
||||
}
|
||||
catch (DataAccessException ex) {
|
||||
if (continueOnError) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("SQL: " + statement + " failed", ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
long elapsedTime = System.currentTimeMillis() - startTime;
|
||||
logger.info("Done executing SQL scriptBuilder '" + sqlResourcePath + "' in " + elapsedTime + " ms");
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new DataAccessResourceFailureException("Failed to open SQL script '" + sqlResourcePath + "'", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test;
|
||||
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
|
||||
/**
|
||||
* Convenient base class for JUnit 3.8 based tests that should occur in a
|
||||
* transaction, but normally will roll the transaction back on the completion of
|
||||
* each test.
|
||||
*
|
||||
* <p>This is useful in a range of circumstances, allowing the following benefits:
|
||||
* <ul>
|
||||
* <li>Ability to delete or insert any data in the database, without affecting
|
||||
* other tests
|
||||
* <li>Providing a transactional context for any code requiring a transaction
|
||||
* <li>Ability to write anything to the database without any need to clean up.
|
||||
* </ul>
|
||||
*
|
||||
* <p>This class is typically very fast, compared to traditional setup/teardown
|
||||
* scripts.
|
||||
*
|
||||
* <p>If data should be left in the database, call the {@link #setComplete()}
|
||||
* method in each test. The {@link #setDefaultRollback "defaultRollback"}
|
||||
* property, which defaults to "true", determines whether transactions will
|
||||
* complete by default.
|
||||
*
|
||||
* <p>It is even possible to end the transaction early; for example, to verify lazy
|
||||
* loading behavior of an O/R mapping tool. (This is a valuable away to avoid
|
||||
* unexpected errors when testing a web UI, for example.) Simply call the
|
||||
* {@link #endTransaction()} method. Execution will then occur without a
|
||||
* transactional context.
|
||||
*
|
||||
* <p>The {@link #startNewTransaction()} method may be called after a call to
|
||||
* {@link #endTransaction()} if you wish to create a new transaction, quite
|
||||
* independent of the old transaction. The new transaction's default fate will
|
||||
* be to roll back, unless {@link #setComplete()} is called again during the
|
||||
* scope of the new transaction. Any number of transactions may be created and
|
||||
* ended in this way. The final transaction will automatically be rolled back
|
||||
* when the test case is torn down.
|
||||
*
|
||||
* <p>Transactional behavior requires a single bean in the context implementing the
|
||||
* {@link PlatformTransactionManager} interface. This will be set by the
|
||||
* superclass's Dependency Injection mechanism. If using the superclass's Field
|
||||
* Injection mechanism, the implementation should be named "transactionManager".
|
||||
* This mechanism allows the use of the
|
||||
* {@link AbstractDependencyInjectionSpringContextTests} superclass even when
|
||||
* there is more than one transaction manager in the context.
|
||||
*
|
||||
* <p><b>This base class can also be used without transaction management, if no
|
||||
* PlatformTransactionManager bean is found in the context provided.</b> Be
|
||||
* careful about using this mode, as it allows the potential to permanently
|
||||
* modify data. This mode is available only if dependency checking is turned off
|
||||
* in the {@link AbstractDependencyInjectionSpringContextTests} superclass. The
|
||||
* non-transactional capability is provided to enable use of the same subclass
|
||||
* in different environments.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 1.1.1
|
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework
|
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractTransactionalSpringContextTests extends AbstractDependencyInjectionSpringContextTests {
|
||||
|
||||
/** The transaction manager to use */
|
||||
protected PlatformTransactionManager transactionManager;
|
||||
|
||||
/** Should we roll back by default? */
|
||||
private boolean defaultRollback = true;
|
||||
|
||||
/** Should we commit the current transaction? */
|
||||
private boolean complete = false;
|
||||
|
||||
/** Number of transactions started */
|
||||
private int transactionsStarted = 0;
|
||||
|
||||
/**
|
||||
* Transaction definition used by this test class: by default, a plain
|
||||
* DefaultTransactionDefinition. Subclasses can change this to cause
|
||||
* different behavior.
|
||||
*/
|
||||
protected TransactionDefinition transactionDefinition= new DefaultTransactionDefinition();
|
||||
|
||||
/**
|
||||
* TransactionStatus for this test. Typical subclasses won't need to use it.
|
||||
*/
|
||||
protected TransactionStatus transactionStatus;
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor for AbstractTransactionalSpringContextTests.
|
||||
*/
|
||||
public AbstractTransactionalSpringContextTests() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for AbstractTransactionalSpringContextTests with a JUnit name.
|
||||
*/
|
||||
public AbstractTransactionalSpringContextTests(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify the transaction manager to use. No transaction management will be
|
||||
* available if this is not set. Populated through dependency injection by
|
||||
* the superclass.
|
||||
* <p>
|
||||
* This mode works only if dependency checking is turned off in the
|
||||
* {@link AbstractDependencyInjectionSpringContextTests} superclass.
|
||||
*/
|
||||
public void setTransactionManager(PlatformTransactionManager transactionManager) {
|
||||
this.transactionManager = transactionManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can set this value in their constructor to change the default,
|
||||
* which is always to roll the transaction back.
|
||||
*/
|
||||
public void setDefaultRollback(final boolean defaultRollback) {
|
||||
this.defaultRollback = defaultRollback;
|
||||
}
|
||||
/**
|
||||
* Get the <em>default rollback</em> flag for this test.
|
||||
* @see #setDefaultRollback(boolean)
|
||||
* @return The <em>default rollback</em> flag.
|
||||
*/
|
||||
protected boolean isDefaultRollback() {
|
||||
return this.defaultRollback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not to rollback transactions for the current test.
|
||||
* <p>The default implementation delegates to {@link #isDefaultRollback()}.
|
||||
* Subclasses can override as necessary.
|
||||
*/
|
||||
protected boolean isRollback() {
|
||||
return isDefaultRollback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method in an overridden {@link #runBare()} method to prevent
|
||||
* transactional execution.
|
||||
*/
|
||||
protected void preventTransaction() {
|
||||
this.transactionDefinition = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method in an overridden {@link #runBare()} method to override
|
||||
* the transaction attributes that will be used, so that {@link #setUp()}
|
||||
* and {@link #tearDown()} behavior is modified.
|
||||
* @param customDefinition the custom transaction definition
|
||||
*/
|
||||
protected void setTransactionDefinition(TransactionDefinition customDefinition) {
|
||||
this.transactionDefinition = customDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation creates a transaction before test execution.
|
||||
* <p>Override {@link #onSetUpBeforeTransaction()} and/or
|
||||
* {@link #onSetUpInTransaction()} to add custom set-up behavior for
|
||||
* transactional execution. Alternatively, override this method for general
|
||||
* set-up behavior, calling <code>super.onSetUp()</code> as part of your
|
||||
* method implementation.
|
||||
* @throws Exception simply let any exception propagate
|
||||
* @see #onTearDown()
|
||||
*/
|
||||
protected void onSetUp() throws Exception {
|
||||
this.complete = !this.isRollback();
|
||||
|
||||
if (this.transactionManager == null) {
|
||||
this.logger.info("No transaction manager set: test will NOT run within a transaction");
|
||||
}
|
||||
else if (this.transactionDefinition == null) {
|
||||
this.logger.info("No transaction definition set: test will NOT run within a transaction");
|
||||
}
|
||||
else {
|
||||
onSetUpBeforeTransaction();
|
||||
startNewTransaction();
|
||||
try {
|
||||
onSetUpInTransaction();
|
||||
}
|
||||
catch (final Exception ex) {
|
||||
endTransaction();
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this method to perform any setup operations, such
|
||||
* as populating a database table, <i>before</i> the transaction created by
|
||||
* this class. Only invoked if there <i>is</i> a transaction: that is, if
|
||||
* {@link #preventTransaction()} has not been invoked in an overridden
|
||||
* {@link #runTest()} method.
|
||||
* @throws Exception simply let any exception propagate
|
||||
*/
|
||||
protected void onSetUpBeforeTransaction() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this method to perform any setup operations, such
|
||||
* as populating a database table, <i>within</i> the transaction created by
|
||||
* this class.
|
||||
* <p><b>NB:</b> Not called if there is no transaction management, due to no
|
||||
* transaction manager being provided in the context.
|
||||
* <p>If any {@link Throwable} is thrown, the transaction that has been started
|
||||
* prior to the execution of this method will be
|
||||
* {@link #endTransaction() ended} (or rather an attempt will be made to
|
||||
* {@link #endTransaction() end it gracefully}); The offending
|
||||
* {@link Throwable} will then be rethrown.
|
||||
* @throws Exception simply let any exception propagate
|
||||
*/
|
||||
protected void onSetUpInTransaction() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation ends the transaction after test execution.
|
||||
* <p>Override {@link #onTearDownInTransaction()} and/or
|
||||
* {@link #onTearDownAfterTransaction()} to add custom tear-down behavior
|
||||
* for transactional execution. Alternatively, override this method for
|
||||
* general tear-down behavior, calling <code>super.onTearDown()</code> as
|
||||
* part of your method implementation.
|
||||
* <p>Note that {@link #onTearDownInTransaction()} will only be called if a
|
||||
* transaction is still active at the time of the test shutdown. In
|
||||
* particular, it will <i>not</i> be called if the transaction has been
|
||||
* completed with an explicit {@link #endTransaction()} call before.
|
||||
* @throws Exception simply let any exception propagate
|
||||
* @see #onSetUp()
|
||||
*/
|
||||
protected void onTearDown() throws Exception {
|
||||
// Call onTearDownInTransaction and end transaction if the transaction
|
||||
// is still active.
|
||||
if (this.transactionStatus != null && !this.transactionStatus.isCompleted()) {
|
||||
try {
|
||||
onTearDownInTransaction();
|
||||
}
|
||||
finally {
|
||||
endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
// Call onTearDownAfterTransaction if there was at least one
|
||||
// transaction, even if it has been completed early through an
|
||||
// endTransaction() call.
|
||||
if (this.transactionsStarted > 0) {
|
||||
onTearDownAfterTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this method to run invariant tests here. The
|
||||
* transaction is <i>still active</i> at this point, so any changes made in
|
||||
* the transaction will still be visible. However, there is no need to clean
|
||||
* up the database, as a rollback will follow automatically.
|
||||
* <p><b>NB:</b> Not called if there is no actual transaction, for example due
|
||||
* to no transaction manager being provided in the application context.
|
||||
* @throws Exception simply let any exception propagate
|
||||
*/
|
||||
protected void onTearDownInTransaction() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this method to perform cleanup after a
|
||||
* transaction here. At this point, the transaction is <i>not active anymore</i>.
|
||||
* @throws Exception simply let any exception propagate
|
||||
*/
|
||||
protected void onTearDownAfterTransaction() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cause the transaction to commit for this test method, even if the test
|
||||
* method is configured to {@link #isRollback() rollback}.
|
||||
* @throws IllegalStateException if the operation cannot be set to complete
|
||||
* as no transaction manager was provided
|
||||
*/
|
||||
protected void setComplete() {
|
||||
if (this.transactionManager == null) {
|
||||
throw new IllegalStateException("No transaction manager set");
|
||||
}
|
||||
this.complete = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Immediately force a commit or rollback of the transaction, according to
|
||||
* the <code>complete</code> and {@link #isRollback() rollback} flags.
|
||||
* <p>Can be used to explicitly let the transaction end early, for example to
|
||||
* check whether lazy associations of persistent objects work outside of a
|
||||
* transaction (that is, have been initialized properly).
|
||||
* @see #setComplete()
|
||||
*/
|
||||
protected void endTransaction() {
|
||||
final boolean commit = this.complete || !isRollback();
|
||||
if (this.transactionStatus != null) {
|
||||
try {
|
||||
if (commit) {
|
||||
this.transactionManager.commit(this.transactionStatus);
|
||||
this.logger.debug("Committed transaction after execution of test [" + getName() + "].");
|
||||
}
|
||||
else {
|
||||
this.transactionManager.rollback(this.transactionStatus);
|
||||
this.logger.debug("Rolled back transaction after execution of test [" + getName() + "].");
|
||||
}
|
||||
}
|
||||
finally {
|
||||
this.transactionStatus = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a new transaction. Only call this method if
|
||||
* {@link #endTransaction()} has been called. {@link #setComplete()} can be
|
||||
* used again in the new transaction. The fate of the new transaction, by
|
||||
* default, will be the usual rollback.
|
||||
* @throws TransactionException if starting the transaction failed
|
||||
*/
|
||||
protected void startNewTransaction() throws TransactionException {
|
||||
if (this.transactionStatus != null) {
|
||||
throw new IllegalStateException("Cannot start new transaction without ending existing transaction: "
|
||||
+ "Invoke endTransaction() before startNewTransaction()");
|
||||
}
|
||||
if (this.transactionManager == null) {
|
||||
throw new IllegalStateException("No transaction manager set");
|
||||
}
|
||||
|
||||
this.transactionStatus = this.transactionManager.getTransaction(this.transactionDefinition);
|
||||
++this.transactionsStarted;
|
||||
this.complete = !this.isRollback();
|
||||
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Began transaction (" + this.transactionsStarted + "): transaction manager ["
|
||||
+ this.transactionManager + "]; rollback [" + this.isRollback() + "].");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Superclass for JUnit 3.8 based tests that allows conditional test execution
|
||||
* at the individual test method level. The
|
||||
* {@link #isDisabledInThisEnvironment(String) isDisabledInThisEnvironment()}
|
||||
* method is invoked before the execution of each test method. Subclasses can
|
||||
* override that method to return whether or not the given test should be
|
||||
* executed. Note that the tests will still appear to have executed and passed;
|
||||
* however, log output will show that the test was not executed.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @since 2.0
|
||||
* @see #isDisabledInThisEnvironment
|
||||
* @deprecated as of Spring 3.0, in favor of using the listener-based test context framework
|
||||
* ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests})
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class ConditionalTestCase extends TestCase {
|
||||
|
||||
private static int disabledTestCount;
|
||||
|
||||
|
||||
/**
|
||||
* Return the number of tests disabled in this environment.
|
||||
*/
|
||||
public static int getDisabledTestCount() {
|
||||
return disabledTestCount;
|
||||
}
|
||||
|
||||
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor for ConditionalTestCase.
|
||||
*/
|
||||
public ConditionalTestCase() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for ConditionalTestCase with a JUnit name.
|
||||
*/
|
||||
public ConditionalTestCase(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public void runBare() throws Throwable {
|
||||
// getName will return the name of the method being run
|
||||
if (isDisabledInThisEnvironment(getName())) {
|
||||
recordDisabled();
|
||||
this.logger.info("**** " + getClass().getName() + "." + getName() + " disabled in this environment: "
|
||||
+ "Total disabled tests = " + getDisabledTestCount());
|
||||
return;
|
||||
}
|
||||
|
||||
// Let JUnit handle execution
|
||||
super.runBare();
|
||||
}
|
||||
|
||||
/**
|
||||
* Should this test run?
|
||||
* @param testMethodName name of the test method
|
||||
* @return whether the test should execute in the current environment
|
||||
*/
|
||||
protected boolean isDisabledInThisEnvironment(String testMethodName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record a disabled test.
|
||||
* @return the current disabled test count
|
||||
*/
|
||||
protected int recordDisabled() {
|
||||
return ++disabledTestCount;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
||||
import org.springframework.transaction.interceptor.TransactionAttributeSource;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Java 5 specific subclass of
|
||||
* {@link AbstractTransactionalDataSourceSpringContextTests}, exposing a
|
||||
* {@link SimpleJdbcTemplate} and obeying annotations for transaction control.
|
||||
* </p>
|
||||
* <p>
|
||||
* For example, test methods can be annotated with the regular Spring
|
||||
* {@link org.springframework.transaction.annotation.Transactional @Transactional}
|
||||
* annotation (e.g., to force execution in a read-only transaction) or with the
|
||||
* {@link NotTransactional @NotTransactional} annotation to prevent any
|
||||
* transaction being created at all. In addition, individual test methods can be
|
||||
* annotated with {@link Rollback @Rollback} to override the
|
||||
* {@link #isDefaultRollback() default rollback} settings.
|
||||
* </p>
|
||||
* <p>
|
||||
* The following list constitutes all annotations currently supported by
|
||||
* AbstractAnnotationAwareTransactionalTests:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>{@link DirtiesContext @DirtiesContext}</li>
|
||||
* <li>{@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration}</li>
|
||||
* <li>{@link IfProfileValue @IfProfileValue}</li>
|
||||
* <li>{@link ExpectedException @ExpectedException}</li>
|
||||
* <li>{@link Timed @Timed}</li>
|
||||
* <li>{@link Repeat @Repeat}</li>
|
||||
* <li>{@link org.springframework.transaction.annotation.Transactional @Transactional}</li>
|
||||
* <li>{@link NotTransactional @NotTransactional}</li>
|
||||
* <li>{@link Rollback @Rollback}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class AbstractAnnotationAwareTransactionalTests extends
|
||||
AbstractTransactionalDataSourceSpringContextTests {
|
||||
|
||||
protected SimpleJdbcTemplate simpleJdbcTemplate;
|
||||
|
||||
private final TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource();
|
||||
|
||||
/**
|
||||
* {@link ProfileValueSource} available to subclasses but primarily intended
|
||||
* for use in {@link #isDisabledInThisEnvironment(Method)}.
|
||||
* <p>Set to {@link SystemProfileValueSource} by default for backwards
|
||||
* compatibility; however, the value may be changed in the
|
||||
* {@link #AbstractAnnotationAwareTransactionalTests(String)} constructor.
|
||||
*/
|
||||
protected ProfileValueSource profileValueSource = SystemProfileValueSource.getInstance();
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor for AbstractAnnotationAwareTransactionalTests, which
|
||||
* delegates to {@link #AbstractAnnotationAwareTransactionalTests(String)}.
|
||||
*/
|
||||
public AbstractAnnotationAwareTransactionalTests() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new AbstractAnnotationAwareTransactionalTests instance with
|
||||
* the specified JUnit <code>name</code> and retrieves the configured (or
|
||||
* default) {@link ProfileValueSource}.
|
||||
* @param name the name of the current test
|
||||
* @see ProfileValueUtils#retrieveProfileValueSource(Class)
|
||||
*/
|
||||
public AbstractAnnotationAwareTransactionalTests(String name) {
|
||||
super(name);
|
||||
this.profileValueSource = ProfileValueUtils.retrieveProfileValueSource(getClass());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
super.setDataSource(dataSource);
|
||||
// JdbcTemplate will be identically configured
|
||||
this.simpleJdbcTemplate = new SimpleJdbcTemplate(this.jdbcTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a unique {@link ProfileValueSource} in the supplied
|
||||
* {@link ApplicationContext}. If found, the
|
||||
* <code>profileValueSource</code> for this test will be set to the unique
|
||||
* {@link ProfileValueSource}.
|
||||
* @param applicationContext the ApplicationContext in which to search for
|
||||
* the ProfileValueSource; may not be <code>null</code>
|
||||
* @deprecated Use {@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
protected void findUniqueProfileValueSourceFromContext(ApplicationContext applicationContext) {
|
||||
Assert.notNull(applicationContext, "Can not search for a ProfileValueSource in a null ApplicationContext.");
|
||||
ProfileValueSource uniqueProfileValueSource = null;
|
||||
Map<?, ?> beans = applicationContext.getBeansOfType(ProfileValueSource.class);
|
||||
if (beans.size() == 1) {
|
||||
uniqueProfileValueSource = (ProfileValueSource) beans.values().iterator().next();
|
||||
}
|
||||
if (uniqueProfileValueSource != null) {
|
||||
this.profileValueSource = uniqueProfileValueSource;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to populate transaction definition from annotations.
|
||||
*/
|
||||
@Override
|
||||
public void runBare() throws Throwable {
|
||||
// getName will return the name of the method being run.
|
||||
if (isDisabledInThisEnvironment(getName())) {
|
||||
// Let superclass log that we didn't run the test.
|
||||
super.runBare();
|
||||
return;
|
||||
}
|
||||
|
||||
final Method testMethod = getTestMethod();
|
||||
|
||||
if (isDisabledInThisEnvironment(testMethod)) {
|
||||
recordDisabled();
|
||||
this.logger.info("**** " + getClass().getName() + "." + getName() + " disabled in this environment: "
|
||||
+ "Total disabled tests=" + getDisabledTestCount());
|
||||
return;
|
||||
}
|
||||
|
||||
TransactionDefinition explicitTransactionDefinition =
|
||||
this.transactionAttributeSource.getTransactionAttribute(testMethod, getClass());
|
||||
if (explicitTransactionDefinition != null) {
|
||||
this.logger.info("Custom transaction definition [" + explicitTransactionDefinition + "] for test method ["
|
||||
+ getName() + "].");
|
||||
setTransactionDefinition(explicitTransactionDefinition);
|
||||
}
|
||||
else if (testMethod.isAnnotationPresent(NotTransactional.class)) {
|
||||
// Don't have any transaction...
|
||||
preventTransaction();
|
||||
}
|
||||
|
||||
// Let JUnit handle execution. We're just changing the state of the test class first.
|
||||
runTestTimed(new TestExecutionCallback() {
|
||||
public void run() throws Throwable {
|
||||
try {
|
||||
AbstractAnnotationAwareTransactionalTests.super.runBare();
|
||||
}
|
||||
finally {
|
||||
// Mark the context to be blown away if the test was
|
||||
// annotated to result in setDirty being invoked
|
||||
// automatically.
|
||||
if (testMethod.isAnnotationPresent(DirtiesContext.class)) {
|
||||
AbstractAnnotationAwareTransactionalTests.this.setDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, testMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the test for the supplied <code>testMethod</code> should
|
||||
* run in the current environment.
|
||||
* <p>The default implementation is based on
|
||||
* {@link IfProfileValue @IfProfileValue} semantics.
|
||||
* @param testMethod the test method
|
||||
* @return <code>true</code> if the test is <em>disabled</em> in the current environment
|
||||
* @see ProfileValueUtils#isTestEnabledInThisEnvironment
|
||||
*/
|
||||
protected boolean isDisabledInThisEnvironment(Method testMethod) {
|
||||
return !ProfileValueUtils.isTestEnabledInThisEnvironment(this.profileValueSource, testMethod, getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current test method.
|
||||
*/
|
||||
protected Method getTestMethod() {
|
||||
assertNotNull("TestCase.getName() cannot be null", getName());
|
||||
Method testMethod = null;
|
||||
try {
|
||||
// Use same algorithm as JUnit itself to retrieve the test method
|
||||
// about to be executed (the method name is returned by getName). It
|
||||
// has to be public so we can retrieve it.
|
||||
testMethod = getClass().getMethod(getName(), (Class[]) null);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
fail("Method '" + getName() + "' not found");
|
||||
}
|
||||
if (!Modifier.isPublic(testMethod.getModifiers())) {
|
||||
fail("Method '" + getName() + "' should be public");
|
||||
}
|
||||
return testMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether or not to rollback transactions for the current test
|
||||
* by taking into consideration the
|
||||
* {@link #isDefaultRollback() default rollback} flag and a possible
|
||||
* method-level override via the {@link Rollback @Rollback} annotation.
|
||||
* @return the <em>rollback</em> flag for the current test
|
||||
*/
|
||||
@Override
|
||||
protected boolean isRollback() {
|
||||
boolean rollback = isDefaultRollback();
|
||||
Rollback rollbackAnnotation = getTestMethod().getAnnotation(Rollback.class);
|
||||
if (rollbackAnnotation != null) {
|
||||
boolean rollbackOverride = rollbackAnnotation.value();
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Method-level @Rollback(" + rollbackOverride + ") overrides default rollback ["
|
||||
+ rollback + "] for test [" + getName() + "].");
|
||||
}
|
||||
rollback = rollbackOverride;
|
||||
}
|
||||
else {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("No method-level @Rollback override: using default rollback [" + rollback
|
||||
+ "] for test [" + getName() + "].");
|
||||
}
|
||||
}
|
||||
return rollback;
|
||||
}
|
||||
|
||||
private void runTestTimed(TestExecutionCallback tec, Method testMethod) throws Throwable {
|
||||
Timed timed = testMethod.getAnnotation(Timed.class);
|
||||
if (timed == null) {
|
||||
runTest(tec, testMethod);
|
||||
}
|
||||
else {
|
||||
long startTime = System.currentTimeMillis();
|
||||
try {
|
||||
runTest(tec, testMethod);
|
||||
}
|
||||
finally {
|
||||
long elapsed = System.currentTimeMillis() - startTime;
|
||||
if (elapsed > timed.millis()) {
|
||||
fail("Took " + elapsed + " ms; limit was " + timed.millis());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void runTest(TestExecutionCallback tec, Method testMethod) throws Throwable {
|
||||
ExpectedException expectedExceptionAnnotation = testMethod.getAnnotation(ExpectedException.class);
|
||||
boolean exceptionIsExpected = (expectedExceptionAnnotation != null && expectedExceptionAnnotation.value() != null);
|
||||
Class<? extends Throwable> expectedException = (exceptionIsExpected ? expectedExceptionAnnotation.value() : null);
|
||||
|
||||
Repeat repeat = testMethod.getAnnotation(Repeat.class);
|
||||
int runs = ((repeat != null) && (repeat.value() > 1)) ? repeat.value() : 1;
|
||||
|
||||
for (int i = 0; i < runs; i++) {
|
||||
try {
|
||||
if (runs > 1 && this.logger != null && this.logger.isInfoEnabled()) {
|
||||
this.logger.info("Repetition " + (i + 1) + " of test " + testMethod.getName());
|
||||
}
|
||||
tec.run();
|
||||
if (exceptionIsExpected) {
|
||||
fail("Expected exception: " + expectedException.getName());
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
if (!exceptionIsExpected) {
|
||||
throw t;
|
||||
}
|
||||
if (!expectedException.isAssignableFrom(t.getClass())) {
|
||||
// Wrap the unexpected throwable with an explicit message.
|
||||
AssertionFailedError assertionError = new AssertionFailedError("Unexpected exception, expected<" +
|
||||
expectedException.getName() + "> but was<" + t.getClass().getName() + ">");
|
||||
assertionError.initCause(t);
|
||||
throw assertionError;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static interface TestExecutionCallback {
|
||||
|
||||
void run() throws Throwable;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Test annotation to indicate that a test method <em>dirties</em> the context
|
||||
* for the current test.
|
||||
* </p>
|
||||
* <p>
|
||||
* Using this annotation in conjunction with
|
||||
* {@link AbstractAnnotationAwareTransactionalTests} is less error-prone than
|
||||
* calling
|
||||
* {@link org.springframework.test.AbstractSingleSpringContextTests#setDirty() setDirty()}
|
||||
* explicitly because the call to <code>setDirty()</code> is guaranteed to
|
||||
* occur, even if the test failed. If only a particular code path in the test
|
||||
* dirties the context, prefer calling <code>setDirty()</code> explicitly --
|
||||
* and take care!
|
||||
* </p>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
* @see org.springframework.test.AbstractSingleSpringContextTests
|
||||
*/
|
||||
@Target( { ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface DirtiesContext {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Test annotation to indicate that a test method is required to throw the
|
||||
* specified exception.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
*/
|
||||
@Target( { ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface ExpectedException {
|
||||
|
||||
Class<? extends Throwable> value();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Test annotation to indicate that a test is enabled for a specific testing
|
||||
* profile or environment. If the configured {@link ProfileValueSource} returns
|
||||
* a matching {@link #value() value} for the provided {@link #name() name}, the
|
||||
* test will be enabled.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note: {@link IfProfileValue @IfProfileValue} can be applied at either the
|
||||
* class or method level.
|
||||
* </p>
|
||||
* <p>
|
||||
* Examples: when using {@link SystemProfileValueSource} as the
|
||||
* {@link ProfileValueSource} implementation, you can configure a test method to
|
||||
* run only on Java VMs from Sun Microsystems as follows:
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
* {@link IfProfileValue @IfProfileValue}(name="java.vendor", value="Sun Microsystems Inc.")
|
||||
* testSomething() {
|
||||
* // ...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* You can alternatively configure {@link IfProfileValue @IfProfileValue} with
|
||||
* <em>OR</em> semantics for multiple {@link #values() values} as follows
|
||||
* (assuming a {@link ProfileValueSource} has been appropriately configured for
|
||||
* the "test-groups" name):
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
* {@link IfProfileValue @IfProfileValue}(name="test-groups", values={"unit-tests", "integration-tests"})
|
||||
* public void testWhichRunsForUnitOrIntegrationTestGroups() {
|
||||
* // ...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
* @see ProfileValueSource
|
||||
* @see ProfileValueSourceConfiguration
|
||||
* @see ProfileValueUtils
|
||||
* @see AbstractAnnotationAwareTransactionalTests
|
||||
* @see org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests
|
||||
* @see org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
*/
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
@Documented
|
||||
public @interface IfProfileValue {
|
||||
|
||||
/**
|
||||
* The <code>name</code> of the <em>profile value</em> against which to test.
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* A single, permissible <code>value</code> of the <em>profile value</em>
|
||||
* for the given {@link #name() name}.
|
||||
* <p>Note: Assigning values to both {@link #value()} and {@link #values()}
|
||||
* will lead to a configuration conflict.
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* A list of all permissible <code>values</code> of the
|
||||
* <em>profile value</em> for the given {@link #name() name}.
|
||||
* <p>Note: Assigning values to both {@link #value()} and {@link #values()}
|
||||
* will lead to a configuration conflict.
|
||||
*/
|
||||
String[] values() default {};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Test annotation to indicate that a method is not transactional.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
*/
|
||||
@Target( { ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface NotTransactional {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.annotation;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Strategy interface for retrieving <em>profile values</em> for a given
|
||||
* testing environment.
|
||||
* </p>
|
||||
* <p>
|
||||
* Concrete implementations must provide a <code>public</code> no-args
|
||||
* constructor.
|
||||
* </p>
|
||||
* <p>
|
||||
* Spring provides the following out-of-the-box implementations:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>{@link SystemProfileValueSource}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
* @see ProfileValueSourceConfiguration
|
||||
* @see IfProfileValue
|
||||
* @see ProfileValueUtils
|
||||
*/
|
||||
public interface ProfileValueSource {
|
||||
|
||||
/**
|
||||
* Get the <em>profile value</em> indicated by the specified key.
|
||||
* @param key the name of the <em>profile value</em>
|
||||
* @return the String value of the <em>profile value</em>, or <code>null</code>
|
||||
* if there is no <em>profile value</em> with that key
|
||||
*/
|
||||
String get(String key);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* ProfileValueSourceConfiguration is a class-level annotation which is used to
|
||||
* specify what type of {@link ProfileValueSource} to use when retrieving
|
||||
* <em>profile values</em> configured via the
|
||||
* {@link IfProfileValue @IfProfileValue} annotation.
|
||||
* </p>
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 2.5
|
||||
* @see ProfileValueSource
|
||||
* @see IfProfileValue
|
||||
* @see ProfileValueUtils
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Inherited
|
||||
@Documented
|
||||
public @interface ProfileValueSourceConfiguration {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The type of {@link ProfileValueSource} to use when retrieving
|
||||
* <em>profile values</em>.
|
||||
* </p>
|
||||
*
|
||||
* @see SystemProfileValueSource
|
||||
*/
|
||||
Class<? extends ProfileValueSource> value() default SystemProfileValueSource.class;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* General utility methods for working with <em>profile values</em>.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
* @see ProfileValueSource
|
||||
* @see ProfileValueSourceConfiguration
|
||||
* @see IfProfileValue
|
||||
*/
|
||||
public abstract class ProfileValueUtils {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ProfileValueUtils.class);
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the {@link ProfileValueSource} type for the specified
|
||||
* {@link Class test class} as configured via the
|
||||
* {@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration}
|
||||
* annotation and instantiates a new instance of that type.
|
||||
* <p>
|
||||
* If
|
||||
* {@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration}
|
||||
* is not present on the specified class or if a custom
|
||||
* {@link ProfileValueSource} is not declared, the default
|
||||
* {@link SystemProfileValueSource} will be returned instead.
|
||||
*
|
||||
* @param testClass The test class for which the ProfileValueSource should
|
||||
* be retrieved
|
||||
* @return the configured (or default) ProfileValueSource for the specified
|
||||
* class
|
||||
* @see SystemProfileValueSource
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ProfileValueSource retrieveProfileValueSource(Class<?> testClass) {
|
||||
Assert.notNull(testClass, "testClass must not be null");
|
||||
|
||||
Class<ProfileValueSourceConfiguration> annotationType = ProfileValueSourceConfiguration.class;
|
||||
ProfileValueSourceConfiguration config = testClass.getAnnotation(annotationType);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Retrieved @ProfileValueSourceConfiguration [" + config + "] for test class ["
|
||||
+ testClass.getName() + "]");
|
||||
}
|
||||
|
||||
Class<? extends ProfileValueSource> profileValueSourceType;
|
||||
if (config != null) {
|
||||
profileValueSourceType = config.value();
|
||||
}
|
||||
else {
|
||||
profileValueSourceType = (Class<? extends ProfileValueSource>) AnnotationUtils.getDefaultValue(annotationType);
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Retrieved ProfileValueSource type [" + profileValueSourceType + "] for class ["
|
||||
+ testClass.getName() + "]");
|
||||
}
|
||||
|
||||
ProfileValueSource profileValueSource;
|
||||
if (SystemProfileValueSource.class.equals(profileValueSourceType)) {
|
||||
profileValueSource = SystemProfileValueSource.getInstance();
|
||||
}
|
||||
else {
|
||||
try {
|
||||
profileValueSource = profileValueSourceType.newInstance();
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Could not instantiate a ProfileValueSource of type [" + profileValueSourceType
|
||||
+ "] for class [" + testClass.getName() + "]: using default.", e);
|
||||
}
|
||||
profileValueSource = SystemProfileValueSource.getInstance();
|
||||
}
|
||||
}
|
||||
|
||||
return profileValueSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the supplied <code>testClass</code> is <em>enabled</em>
|
||||
* in the current environment, as specified by the
|
||||
* {@link IfProfileValue @IfProfileValue} annotation at the class level.
|
||||
* <p>
|
||||
* Defaults to <code>true</code> if no
|
||||
* {@link IfProfileValue @IfProfileValue} annotation is declared.
|
||||
*
|
||||
* @param testClass the test class
|
||||
* @return <code>true</code> if the test is <em>enabled</em> in the
|
||||
* current environment
|
||||
*/
|
||||
public static boolean isTestEnabledInThisEnvironment(Class<?> testClass) {
|
||||
IfProfileValue ifProfileValue = testClass.getAnnotation(IfProfileValue.class);
|
||||
if (ifProfileValue == null) {
|
||||
return true;
|
||||
}
|
||||
ProfileValueSource profileValueSource = retrieveProfileValueSource(testClass);
|
||||
return isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the supplied <code>testMethod</code> is <em>enabled</em>
|
||||
* in the current environment, as specified by the
|
||||
* {@link IfProfileValue @IfProfileValue} annotation, which may be declared
|
||||
* on the test method itself or at the class level.
|
||||
* <p>
|
||||
* Defaults to <code>true</code> if no
|
||||
* {@link IfProfileValue @IfProfileValue} annotation is declared.
|
||||
*
|
||||
* @param testMethod the test method
|
||||
* @param testClass the test class
|
||||
* @return <code>true</code> if the test is <em>enabled</em> in the
|
||||
* current environment
|
||||
*/
|
||||
public static boolean isTestEnabledInThisEnvironment(Method testMethod, Class<?> testClass) {
|
||||
IfProfileValue ifProfileValue = testMethod.getAnnotation(IfProfileValue.class);
|
||||
if (ifProfileValue == null) {
|
||||
ifProfileValue = testClass.getAnnotation(IfProfileValue.class);
|
||||
if (ifProfileValue == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ProfileValueSource profileValueSource = retrieveProfileValueSource(testClass);
|
||||
return isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the supplied <code>testMethod</code> is <em>enabled</em>
|
||||
* in the current environment, as specified by the
|
||||
* {@link IfProfileValue @IfProfileValue} annotation, which may be declared
|
||||
* on the test method itself or at the class level.
|
||||
* <p>
|
||||
* Defaults to <code>true</code> if no
|
||||
* {@link IfProfileValue @IfProfileValue} annotation is declared.
|
||||
*
|
||||
* @param profileValueSource the ProfileValueSource to use to determine if
|
||||
* the test is enabled
|
||||
* @param testMethod the test method
|
||||
* @param testClass the test class
|
||||
* @return <code>true</code> if the test is <em>enabled</em> in the
|
||||
* current environment
|
||||
*/
|
||||
public static boolean isTestEnabledInThisEnvironment(ProfileValueSource profileValueSource, Method testMethod,
|
||||
Class<?> testClass) {
|
||||
|
||||
IfProfileValue ifProfileValue = testMethod.getAnnotation(IfProfileValue.class);
|
||||
if (ifProfileValue == null) {
|
||||
ifProfileValue = testClass.getAnnotation(IfProfileValue.class);
|
||||
if (ifProfileValue == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return isTestEnabledInThisEnvironment(profileValueSource, ifProfileValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the <code>value</code> (or one of the <code>values</code>)
|
||||
* in the supplied {@link IfProfileValue @IfProfileValue} annotation is
|
||||
* <em>enabled</em> in the current environment.
|
||||
*
|
||||
* @param profileValueSource the ProfileValueSource to use to determine if
|
||||
* the test is enabled
|
||||
* @param ifProfileValue the annotation to introspect
|
||||
* @return <code>true</code> if the test is <em>enabled</em> in the
|
||||
* current environment
|
||||
*/
|
||||
private static boolean isTestEnabledInThisEnvironment(ProfileValueSource profileValueSource,
|
||||
IfProfileValue ifProfileValue) {
|
||||
|
||||
String environmentValue = profileValueSource.get(ifProfileValue.name());
|
||||
String[] annotatedValues = ifProfileValue.values();
|
||||
if (StringUtils.hasLength(ifProfileValue.value())) {
|
||||
if (annotatedValues.length > 0) {
|
||||
throw new IllegalArgumentException("Setting both the 'value' and 'values' attributes "
|
||||
+ "of @IfProfileValue is not allowed: choose one or the other.");
|
||||
}
|
||||
annotatedValues = new String[] { ifProfileValue.value() };
|
||||
}
|
||||
|
||||
for (String value : annotatedValues) {
|
||||
if (ObjectUtils.nullSafeEquals(value, environmentValue)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Test annotation to indicate that a test method should be invoked repeatedly.
|
||||
* <p />
|
||||
* Note that the scope of execution to be repeated includes execution of the
|
||||
* test method itself as well as any <em>set up</em> or <em>tear down</em>
|
||||
* of the test fixture.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
*/
|
||||
@Target( { ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Repeat {
|
||||
|
||||
int value() default 1;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Test annotation to indicate whether or not the transaction for the annotated
|
||||
* test method should be <em>rolled back</em> after the test method has
|
||||
* completed. If <code>true</code>, the transaction will be rolled back;
|
||||
* otherwise, the transaction will be committed.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 2.5
|
||||
*/
|
||||
@Target( { ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Rollback {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Whether or not the transaction for the annotated method should be rolled
|
||||
* back after the method has completed.
|
||||
* </p>
|
||||
*/
|
||||
boolean value() default true;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.annotation;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Implementation of {@link ProfileValueSource} which uses system properties as
|
||||
* the underlying source.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
*/
|
||||
public class SystemProfileValueSource implements ProfileValueSource {
|
||||
|
||||
private static final SystemProfileValueSource INSTANCE = new SystemProfileValueSource();
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the canonical instance of this ProfileValueSource.
|
||||
*/
|
||||
public static final SystemProfileValueSource getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Private constructor, enforcing the singleton pattern.
|
||||
*/
|
||||
private SystemProfileValueSource() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <em>profile value</em> indicated by the specified key from the
|
||||
* system properties.
|
||||
* @see System#getProperty(String)
|
||||
*/
|
||||
public String get(String key) {
|
||||
Assert.hasText(key, "'key' must not be empty");
|
||||
return System.getProperty(key);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Test-specific annotation to indicate that a test method has to finish
|
||||
* execution in a {@link #millis() specified time period}.
|
||||
* </p>
|
||||
* <p>
|
||||
* If the text execution takes longer than the specified time period, then the
|
||||
* test is to be considered failed.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that the time period includes execution of the test method itself, any
|
||||
* {@link Repeat repetitions} of the test, and any <em>set up</em> or
|
||||
* <em>tear down</em> of the test fixture.
|
||||
* </p>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
* @see Repeat
|
||||
* @see AbstractAnnotationAwareTransactionalTests
|
||||
*/
|
||||
@Target({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Timed {
|
||||
|
||||
/**
|
||||
* The maximum amount of time (in milliseconds) that a test execution can
|
||||
* take without being marked as failed due to taking too long.
|
||||
*/
|
||||
long millis();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.jdbc;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* JdbcTestUtils is a collection of JDBC related utility methods for
|
||||
* use in unit and integration testing scenarios.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @since 2.5.4
|
||||
*/
|
||||
public class JdbcTestUtils {
|
||||
|
||||
/**
|
||||
* Read a script from the LineNumberReaded and build a String containing the lines.
|
||||
* @param lineNumberReader the <code>LineNumberReader</> containing the script to be processed
|
||||
* @return <code>String</code> containing the script lines
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String readScript(LineNumberReader lineNumberReader) throws IOException {
|
||||
String currentStatement = lineNumberReader.readLine();
|
||||
StringBuilder scriptBuilder = new StringBuilder();
|
||||
while (currentStatement != null) {
|
||||
if (StringUtils.hasText(currentStatement)) {
|
||||
if (scriptBuilder.length() > 0) {
|
||||
scriptBuilder.append('\n');
|
||||
}
|
||||
scriptBuilder.append(currentStatement);
|
||||
}
|
||||
currentStatement = lineNumberReader.readLine();
|
||||
}
|
||||
return scriptBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the provided SQL script contain the specified delimiter?
|
||||
* @param script the SQL script
|
||||
* @param delim charecter delimiting each statement - typically a ';' character
|
||||
*/
|
||||
public static boolean containsSqlScriptDelimiters(String script, char delim) {
|
||||
boolean inLiteral = false;
|
||||
char[] content = script.toCharArray();
|
||||
for (int i = 0; i < script.length(); i++) {
|
||||
if (content[i] == '\'') {
|
||||
inLiteral = !inLiteral;
|
||||
}
|
||||
if (content[i] == delim && !inLiteral) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split an SQL script into separate statements delimited with the provided delimiter character. Each
|
||||
* individual statement will be added to the provided <code>List</code>.
|
||||
* @param script the SQL script
|
||||
* @param delim charecter delimiting each statement - typically a ';' character
|
||||
* @param statements the List that will contain the individual statements
|
||||
*/
|
||||
public static void splitSqlScript(String script, char delim, List<String> statements) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean inLiteral = false;
|
||||
char[] content = script.toCharArray();
|
||||
for (int i = 0; i < script.length(); i++) {
|
||||
if (content[i] == '\'') {
|
||||
inLiteral = !inLiteral;
|
||||
}
|
||||
if (content[i] == delim && !inLiteral) {
|
||||
if (sb.length() > 0) {
|
||||
statements.add(sb.toString());
|
||||
sb = new StringBuilder();
|
||||
}
|
||||
}
|
||||
else {
|
||||
sb.append(content[i]);
|
||||
}
|
||||
}
|
||||
if (sb.length() > 0) {
|
||||
statements.add(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.jpa;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver;
|
||||
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
import org.springframework.instrument.classloading.ResourceOverridingShadowingClassLoader;
|
||||
import org.springframework.instrument.classloading.ShadowingClassLoader;
|
||||
import org.springframework.orm.jpa.ExtendedEntityManagerCreator;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.SharedEntityManagerCreator;
|
||||
import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager;
|
||||
import org.springframework.test.annotation.AbstractAnnotationAwareTransactionalTests;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Convenient support class for JPA-related tests. Offers the same contract as
|
||||
* AbstractTransactionalDataSourceSpringContextTests and equally good performance,
|
||||
* even when performing the instrumentation required by the JPA specification.
|
||||
*
|
||||
* <p>Exposes an EntityManagerFactory and a shared EntityManager.
|
||||
* Requires an EntityManagerFactory to be injected, plus the DataSource and
|
||||
* JpaTransactionManager through the superclass.
|
||||
*
|
||||
* <p>When using Xerces, make sure a post 2.0.2 version is available on the classpath
|
||||
* to avoid a critical
|
||||
* <a href="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16014"/>bug</a>
|
||||
* that leads to StackOverflow. Maven users are likely to encounter this problem since
|
||||
* 2.0.2 is used by default.
|
||||
*
|
||||
* <p>A workaround is to explicitly specify the Xerces version inside the Maven POM:
|
||||
* <pre>
|
||||
* <dependency>
|
||||
* <groupId>xerces</groupId>
|
||||
* <artifactId>xercesImpl</artifactId>
|
||||
* <version>2.8.1</version>
|
||||
* </dependency>
|
||||
* </pre>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class AbstractJpaTests extends AbstractAnnotationAwareTransactionalTests {
|
||||
|
||||
private static final String DEFAULT_ORM_XML_LOCATION = "META-INF/orm.xml";
|
||||
|
||||
/**
|
||||
* Map from String defining unique combination of config locations, to ApplicationContext.
|
||||
* Values are intentionally not strongly typed, to avoid potential class cast exceptions
|
||||
* through use between different class loaders.
|
||||
*/
|
||||
private static Map<String, Object> contextCache = new HashMap<String, Object>();
|
||||
|
||||
private static Map<String, ClassLoader> classLoaderCache = new HashMap<String, ClassLoader>();
|
||||
|
||||
protected EntityManagerFactory entityManagerFactory;
|
||||
|
||||
/**
|
||||
* If this instance is in a shadow loader, this variable
|
||||
* will contain the parent instance of the subclass.
|
||||
* The class will not be the same as the class of the
|
||||
* shadow instance, as it was loaded by a different class loader,
|
||||
* but it can be invoked reflectively. The shadowParent
|
||||
* and the shadow loader can communicate reflectively
|
||||
* but not through direct invocation.
|
||||
*/
|
||||
private Object shadowParent;
|
||||
|
||||
/**
|
||||
* Subclasses can use this in test cases.
|
||||
* It will participate in any current transaction.
|
||||
*/
|
||||
protected EntityManager sharedEntityManager;
|
||||
|
||||
|
||||
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
|
||||
this.entityManagerFactory = entityManagerFactory;
|
||||
this.sharedEntityManager = SharedEntityManagerCreator.createSharedEntityManager(this.entityManagerFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an EntityManager that will always automatically enlist itself in current
|
||||
* transactions, in contrast to an EntityManager returned by
|
||||
* <code>EntityManagerFactory.createEntityManager()</code>
|
||||
* (which requires an explicit <code>joinTransaction()</code> call).
|
||||
*/
|
||||
protected EntityManager createContainerManagedEntityManager() {
|
||||
return ExtendedEntityManagerCreator.createContainerManagedEntityManager(this.entityManagerFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override this method if they wish to disable shadow class loading.
|
||||
* <p>The default implementation deactivates shadow class loading if Spring's
|
||||
* InstrumentationSavingAgent has been configured on VM startup.
|
||||
*/
|
||||
protected boolean shouldUseShadowLoader() {
|
||||
return !InstrumentationLoadTimeWeaver.isInstrumentationAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirty() {
|
||||
super.setDirty();
|
||||
contextCache.remove(cacheKeys());
|
||||
classLoaderCache.remove(cacheKeys());
|
||||
|
||||
// If we are a shadow loader, we need to invoke
|
||||
// the shadow parent to set it dirty, as
|
||||
// it is the shadow parent that maintains the cache state,
|
||||
// not the child
|
||||
if (this.shadowParent != null) {
|
||||
try {
|
||||
Method m = shadowParent.getClass().getMethod("setDirty", (Class[]) null);
|
||||
m.invoke(shadowParent, (Object[]) null);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void runBare() throws Throwable {
|
||||
if (!shouldUseShadowLoader()) {
|
||||
super.runBare();
|
||||
return;
|
||||
}
|
||||
|
||||
String combinationOfContextLocationsForThisTestClass = cacheKeys();
|
||||
ClassLoader classLoaderForThisTestClass = getClass().getClassLoader();
|
||||
// save the TCCL
|
||||
ClassLoader initialClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
if (this.shadowParent != null) {
|
||||
Thread.currentThread().setContextClassLoader(classLoaderForThisTestClass);
|
||||
super.runBare();
|
||||
}
|
||||
|
||||
else {
|
||||
ShadowingClassLoader shadowingClassLoader = (ShadowingClassLoader) classLoaderCache.get(combinationOfContextLocationsForThisTestClass);
|
||||
|
||||
if (shadowingClassLoader == null) {
|
||||
shadowingClassLoader = (ShadowingClassLoader) createShadowingClassLoader(classLoaderForThisTestClass);
|
||||
classLoaderCache.put(combinationOfContextLocationsForThisTestClass, shadowingClassLoader);
|
||||
}
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(shadowingClassLoader);
|
||||
String[] configLocations = getConfigLocations();
|
||||
|
||||
// Do not strongly type, to avoid ClassCastException.
|
||||
Object cachedContext = contextCache.get(combinationOfContextLocationsForThisTestClass);
|
||||
|
||||
if (cachedContext == null) {
|
||||
|
||||
// Create the LoadTimeWeaver.
|
||||
Class shadowingLoadTimeWeaverClass = shadowingClassLoader.loadClass(ShadowingLoadTimeWeaver.class.getName());
|
||||
Constructor constructor = shadowingLoadTimeWeaverClass.getConstructor(ClassLoader.class);
|
||||
constructor.setAccessible(true);
|
||||
Object ltw = constructor.newInstance(shadowingClassLoader);
|
||||
|
||||
// Create the BeanFactory.
|
||||
Class beanFactoryClass = shadowingClassLoader.loadClass(DefaultListableBeanFactory.class.getName());
|
||||
Object beanFactory = BeanUtils.instantiateClass(beanFactoryClass);
|
||||
|
||||
// Create the BeanDefinitionReader.
|
||||
Class beanDefinitionReaderClass = shadowingClassLoader.loadClass(XmlBeanDefinitionReader.class.getName());
|
||||
Class beanDefinitionRegistryClass = shadowingClassLoader.loadClass(BeanDefinitionRegistry.class.getName());
|
||||
Object reader = beanDefinitionReaderClass.getConstructor(beanDefinitionRegistryClass).newInstance(beanFactory);
|
||||
|
||||
// Load the bean definitions into the BeanFactory.
|
||||
Method loadBeanDefinitions = beanDefinitionReaderClass.getMethod("loadBeanDefinitions", String[].class);
|
||||
loadBeanDefinitions.invoke(reader, new Object[] {configLocations});
|
||||
|
||||
// Create LoadTimeWeaver-injecting BeanPostProcessor.
|
||||
Class loadTimeWeaverInjectingBeanPostProcessorClass = shadowingClassLoader.loadClass(LoadTimeWeaverInjectingBeanPostProcessor.class.getName());
|
||||
Class loadTimeWeaverClass = shadowingClassLoader.loadClass(LoadTimeWeaver.class.getName());
|
||||
Constructor bppConstructor = loadTimeWeaverInjectingBeanPostProcessorClass.getConstructor(loadTimeWeaverClass);
|
||||
bppConstructor.setAccessible(true);
|
||||
Object beanPostProcessor = bppConstructor.newInstance(ltw);
|
||||
|
||||
// Add LoadTimeWeaver-injecting BeanPostProcessor.
|
||||
Class beanPostProcessorClass = shadowingClassLoader.loadClass(BeanPostProcessor.class.getName());
|
||||
Method addBeanPostProcessor = beanFactoryClass.getMethod("addBeanPostProcessor", beanPostProcessorClass);
|
||||
addBeanPostProcessor.invoke(beanFactory, beanPostProcessor);
|
||||
|
||||
// Create the GenericApplicationContext.
|
||||
Class genericApplicationContextClass = shadowingClassLoader.loadClass(GenericApplicationContext.class.getName());
|
||||
Class defaultListableBeanFactoryClass = shadowingClassLoader.loadClass(DefaultListableBeanFactory.class.getName());
|
||||
cachedContext = genericApplicationContextClass.getConstructor(defaultListableBeanFactoryClass).newInstance(beanFactory);
|
||||
|
||||
// Invoke the context's "refresh" method.
|
||||
genericApplicationContextClass.getMethod("refresh").invoke(cachedContext);
|
||||
|
||||
// Store the context reference in the cache.
|
||||
contextCache.put(combinationOfContextLocationsForThisTestClass, cachedContext);
|
||||
}
|
||||
// create the shadowed test
|
||||
Class shadowedTestClass = shadowingClassLoader.loadClass(getClass().getName());
|
||||
|
||||
// So long as JUnit is excluded from shadowing we
|
||||
// can minimize reflective invocation here
|
||||
TestCase shadowedTestCase = (TestCase) BeanUtils.instantiateClass(shadowedTestClass);
|
||||
|
||||
/* shadowParent = this */
|
||||
Class thisShadowedClass = shadowingClassLoader.loadClass(AbstractJpaTests.class.getName());
|
||||
Field shadowed = thisShadowedClass.getDeclaredField("shadowParent");
|
||||
shadowed.setAccessible(true);
|
||||
shadowed.set(shadowedTestCase, this);
|
||||
|
||||
/* AbstractSpringContextTests.addContext(Object, ApplicationContext) */
|
||||
Class applicationContextClass = shadowingClassLoader.loadClass(ConfigurableApplicationContext.class.getName());
|
||||
Method addContextMethod = shadowedTestClass.getMethod("addContext", Object.class, applicationContextClass);
|
||||
addContextMethod.invoke(shadowedTestCase, configLocations, cachedContext);
|
||||
|
||||
// Invoke tests on shadowed test case
|
||||
shadowedTestCase.setName(getName());
|
||||
shadowedTestCase.runBare();
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
// Unwrap this for better exception reporting
|
||||
// when running tests
|
||||
throw ex.getTargetException();
|
||||
}
|
||||
finally {
|
||||
Thread.currentThread().setContextClassLoader(initialClassLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String cacheKeys() {
|
||||
return StringUtils.arrayToCommaDelimitedString(getConfigLocations());
|
||||
}
|
||||
|
||||
/**
|
||||
* NB: This method must <b>not</b> have a return type of ShadowingClassLoader as that would cause that
|
||||
* class to be loaded eagerly when this test case loads, creating verify errors at runtime.
|
||||
*/
|
||||
protected ClassLoader createShadowingClassLoader(ClassLoader classLoader) {
|
||||
OrmXmlOverridingShadowingClassLoader orxl = new OrmXmlOverridingShadowingClassLoader(classLoader,
|
||||
getActualOrmXmlLocation());
|
||||
customizeResourceOverridingShadowingClassLoader(orxl);
|
||||
return orxl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize the shadowing class loader.
|
||||
* @param shadowingClassLoader this parameter is actually of type
|
||||
* ResourceOverridingShadowingClassLoader, and can safely to be cast to
|
||||
* that type. However, the signature must not be of that type as that
|
||||
* would cause the present class loader to load that type.
|
||||
*/
|
||||
protected void customizeResourceOverridingShadowingClassLoader(ClassLoader shadowingClassLoader) {
|
||||
// empty
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this to return the real location path for
|
||||
* orm.xml or null if they do not wish to find any orm.xml
|
||||
* @return orm.xml path or null to hide any such file
|
||||
*/
|
||||
protected String getActualOrmXmlLocation() {
|
||||
return DEFAULT_ORM_XML_LOCATION;
|
||||
}
|
||||
|
||||
|
||||
private static class LoadTimeWeaverInjectingBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
|
||||
|
||||
private final LoadTimeWeaver ltw;
|
||||
|
||||
public LoadTimeWeaverInjectingBeanPostProcessor(LoadTimeWeaver ltw) {
|
||||
this.ltw = ltw;
|
||||
}
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean instanceof LocalContainerEntityManagerFactoryBean) {
|
||||
((LocalContainerEntityManagerFactoryBean) bean).setLoadTimeWeaver(this.ltw);
|
||||
}
|
||||
if (bean instanceof DefaultPersistenceUnitManager) {
|
||||
((DefaultPersistenceUnitManager) bean).setLoadTimeWeaver(this.ltw);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class ShadowingLoadTimeWeaver implements LoadTimeWeaver {
|
||||
|
||||
private final ClassLoader shadowingClassLoader;
|
||||
|
||||
public ShadowingLoadTimeWeaver(ClassLoader shadowingClassLoader) {
|
||||
this.shadowingClassLoader = shadowingClassLoader;
|
||||
}
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
try {
|
||||
Method addClassFileTransformer =
|
||||
this.shadowingClassLoader.getClass().getMethod("addTransformer", ClassFileTransformer.class);
|
||||
addClassFileTransformer.setAccessible(true);
|
||||
addClassFileTransformer.invoke(this.shadowingClassLoader, transformer);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ClassLoader getInstrumentableClassLoader() {
|
||||
return this.shadowingClassLoader;
|
||||
}
|
||||
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
// Be sure to copy the same resource overrides and same class file transformers:
|
||||
// We want the throwaway class loader to behave like the instrumentable class loader.
|
||||
ResourceOverridingShadowingClassLoader roscl =
|
||||
new ResourceOverridingShadowingClassLoader(getClass().getClassLoader());
|
||||
if (this.shadowingClassLoader instanceof ShadowingClassLoader) {
|
||||
roscl.copyTransformers((ShadowingClassLoader) this.shadowingClassLoader);
|
||||
}
|
||||
if (this.shadowingClassLoader instanceof ResourceOverridingShadowingClassLoader) {
|
||||
roscl.copyOverrides((ResourceOverridingShadowingClassLoader) this.shadowingClassLoader);
|
||||
}
|
||||
return roscl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.jpa;
|
||||
|
||||
import org.springframework.instrument.classloading.ResourceOverridingShadowingClassLoader;
|
||||
|
||||
/**
|
||||
* Subclass of ShadowingClassLoader that overrides attempts to
|
||||
* locate <code>orm.xml</code>.
|
||||
*
|
||||
* <p>This class must <b>not</b> be an inner class of AbstractJpaTests
|
||||
* to avoid it being loaded until first used.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Adrian Colyer
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
*/
|
||||
class OrmXmlOverridingShadowingClassLoader extends ResourceOverridingShadowingClassLoader {
|
||||
|
||||
/**
|
||||
* Default location of the <code>orm.xml</code> file in the class path:
|
||||
* "META-INF/orm.xml"
|
||||
*/
|
||||
public static final String DEFAULT_ORM_XML_LOCATION = "META-INF/orm.xml";
|
||||
|
||||
|
||||
public OrmXmlOverridingShadowingClassLoader(ClassLoader loader, String realOrmXmlLocation) {
|
||||
super(loader);
|
||||
|
||||
// Automatically exclude classes from these well-known persistence providers.
|
||||
// Do NOT exclude Hibernate classes --
|
||||
// this causes class casts due to use of CGLIB by Hibernate.
|
||||
// Same goes for OpenJPA which will not enhance the domain classes.
|
||||
excludePackage("oracle.toplink.essentials");
|
||||
excludePackage("junit");
|
||||
|
||||
override(DEFAULT_ORM_XML_LOCATION, realOrmXmlLocation);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.transaction;
|
||||
|
||||
import javax.transaction.Status;
|
||||
import javax.transaction.Synchronization;
|
||||
import javax.transaction.xa.XAResource;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 31.08.2004
|
||||
*/
|
||||
public class MockJtaTransaction implements javax.transaction.Transaction {
|
||||
|
||||
private Synchronization synchronization;
|
||||
|
||||
public int getStatus() {
|
||||
return Status.STATUS_ACTIVE;
|
||||
}
|
||||
|
||||
public void registerSynchronization(Synchronization synchronization) {
|
||||
this.synchronization = synchronization;
|
||||
}
|
||||
|
||||
public Synchronization getSynchronization() {
|
||||
return synchronization;
|
||||
}
|
||||
|
||||
public boolean enlistResource(XAResource xaResource) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean delistResource(XAResource xaResource, int i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
}
|
||||
|
||||
public void rollback() {
|
||||
}
|
||||
|
||||
public void setRollbackOnly() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* The Spring Framework is published under the terms
|
||||
* of the Apache Software License.
|
||||
*/
|
||||
|
||||
package org.springframework.util;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.NotSerializableException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.beans.TestBean;
|
||||
|
||||
/**
|
||||
* Utilities for testing serializability of objects.
|
||||
* Exposes static methods for use in other test cases.
|
||||
* Extends TestCase only to test itself.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
public class SerializationTestUtils extends TestCase {
|
||||
|
||||
public static void testSerialization(Object o) throws IOException {
|
||||
OutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject(o);
|
||||
}
|
||||
|
||||
public static boolean isSerializable(Object o) throws IOException {
|
||||
try {
|
||||
testSerialization(o);
|
||||
return true;
|
||||
}
|
||||
catch (NotSerializableException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Object serializeAndDeserialize(Object o) throws IOException, ClassNotFoundException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject(o);
|
||||
oos.flush();
|
||||
baos.flush();
|
||||
byte[] bytes = baos.toByteArray();
|
||||
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
|
||||
ObjectInputStream ois = new ObjectInputStream(is);
|
||||
Object o2 = ois.readObject();
|
||||
|
||||
return o2;
|
||||
}
|
||||
|
||||
public SerializationTestUtils(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public void testWithNonSerializableObject() throws IOException {
|
||||
TestBean o = new TestBean();
|
||||
assertFalse(o instanceof Serializable);
|
||||
|
||||
assertFalse(isSerializable(o));
|
||||
|
||||
try {
|
||||
testSerialization(o);
|
||||
fail();
|
||||
}
|
||||
catch (NotSerializableException ex) {
|
||||
// Ok
|
||||
}
|
||||
}
|
||||
|
||||
public void testWithSerializableObject() throws Exception {
|
||||
int x = 5;
|
||||
int y = 10;
|
||||
Point p = new Point(x, y);
|
||||
assertTrue(p instanceof Serializable);
|
||||
|
||||
testSerialization(p);
|
||||
|
||||
assertTrue(isSerializable(p));
|
||||
|
||||
Point p2 = (Point) serializeAndDeserialize(p);
|
||||
assertNotSame(p, p2);
|
||||
assertEquals(x, (int) p2.getX());
|
||||
assertEquals(y, (int) p2.getY());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user