/*
* Copyright 2002-2016 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.junit.Test;
import org.springframework.orm.jpa.domain.DriversLicense;
import org.springframework.orm.jpa.domain.Person;
import org.springframework.util.SerializationTestUtils;
import static org.junit.Assert.*;
/**
* Integration tests for LocalContainerEntityManagerFactoryBean.
* Uses an in-memory database.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public abstract class AbstractContainerEntityManagerFactoryIntegrationTests extends AbstractEntityManagerFactoryIntegrationTests {
@Test
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());
}
@Test
public void testStateClean() {
assertEquals("Should be no people from previous transactions", 0, countRowsInTable("person"));
}
@Test
public void testJdbcTx1_1() {
testJdbcTx2();
}
@Test
public void testJdbcTx1_2() {
testJdbcTx2();
}
@Test
public void testJdbcTx1_3() {
testJdbcTx2();
}
@Test
public void testJdbcTx2() {
assertEquals("Any previous tx must have been rolled back", 0, countRowsInTable("person"));
executeSqlScript("/org/springframework/orm/jpa/insertPerson.sql");
}
@Test
@SuppressWarnings({ "unused", "unchecked" })
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());
}
@Test
public void testBogusQuery() {
try {
Query query = sharedEntityManager.createQuery("It's raining toads");
// required in OpenJPA case
query.executeUpdate();
fail("Should have thrown a RuntimeException");
}
catch (RuntimeException ex) {
// expected
}
}
@Test
public void testGetReferenceWhenNoRow() {
try {
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();
fail("Should have thrown an EntityNotFoundException");
}
catch (EntityNotFoundException ex) {
// expected
}
}
@Test
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("person", "drivers_license");
}
}
@Test
@SuppressWarnings("unchecked")
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 void insertPerson(String firstName) {
String INSERT_PERSON = "INSERT INTO PERSON (ID, FIRST_NAME, LAST_NAME) VALUES (?, ?, ?)";
jdbcTemplate.update(INSERT_PERSON, 1, firstName, "Blair");
}
@Test
public void testEntityManagerProxyRejectsProgrammaticTxManagement() {
try {
sharedEntityManager.getTransaction();
fail("Should not be able to create transactions on container managed EntityManager");
}
catch (IllegalStateException ex) {
}
}
@Test
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"));
}
@Test
@SuppressWarnings("unchecked")
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
}
}
@Test
@SuppressWarnings("unchecked")
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
}
}
@Test
@SuppressWarnings({ "unused", "unchecked" })
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
}
}
@Test
@SuppressWarnings("unchecked")
public void testQueryNoPersonsSharedNotTransactional() {
endTransaction();
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) {
// We would typically expect an IllegalStateException, but Hibernate throws a
// PersistenceException. So we assert the contents of the exception message instead.
assertTrue(ex.getMessage().contains("closed"));
}
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
}
}
@Test
public void testCanSerializeProxies() throws Exception {
assertNotNull(SerializationTestUtils.serializeAndDeserialize(entityManagerFactory));
assertNotNull(SerializationTestUtils.serializeAndDeserialize(sharedEntityManager));
}
}