/* * 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.integration.jpa.core; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import javax.persistence.EntityManager; import org.junit.Assert; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.integration.jpa.support.parametersource.ExpressionEvaluatingParameterSourceFactory; import org.springframework.integration.jpa.support.parametersource.ParameterSource; import org.springframework.integration.jpa.support.parametersource.ParameterSourceFactory; import org.springframework.integration.jpa.test.JpaTestUtils; import org.springframework.integration.jpa.test.entity.Gender; import org.springframework.integration.jpa.test.entity.StudentDomain; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.DefaultTransactionDefinition; /** * @author Gunnar Hillert * @author Gary Russell * @since 2.2 * */ @Transactional public class AbstractJpaOperationsTests { @Autowired protected PlatformTransactionManager transactionManager; @Autowired protected EntityManager entityManager; public void testGetAllStudents() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final List<?> students = jpaOperations.getResultListForClass(StudentDomain.class, 0, 0); Assert.assertTrue(students.size() == 3); } public void testGetAllStudentsWithMaxResults() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final List<?> students = jpaOperations.getResultListForClass(StudentDomain.class, 0, 2); Assert.assertTrue(String.format("Was expecting 2 Students to be returned but got '%s'.", students.size()), students.size() == 2); } public void testExecuteUpdate() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final StudentDomain student = JpaTestUtils.getTestStudent(); List<?> students = jpaOperations.getResultListForClass(StudentDomain.class, 0, 0); Assert.assertTrue(students.size() == 3); ParameterSourceFactory requestParameterSourceFactory = new ExpressionEvaluatingParameterSourceFactory(mock(BeanFactory.class)); ParameterSource source = requestParameterSourceFactory.createParameterSource(student); int updatedRecords = jpaOperations.executeUpdate("update Student s " + "set s.lastName = :lastName, s.lastUpdated = :lastUpdated " + "where s.rollNumber in (select max(a.rollNumber) from Student a)", source); entityManager.flush(); Assert.assertTrue(1 == updatedRecords); Assert.assertNull(student.getRollNumber()); } public void testExecuteUpdateWithNamedQuery() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final StudentDomain student = JpaTestUtils.getTestStudent(); ParameterSourceFactory requestParameterSourceFactory = new ExpressionEvaluatingParameterSourceFactory(mock(BeanFactory.class)); ParameterSource source = requestParameterSourceFactory.createParameterSource(student); int updatedRecords = jpaOperations.executeUpdateWithNamedQuery("updateStudent", source); entityManager.flush(); Assert.assertTrue(1 == updatedRecords); Assert.assertNull(student.getRollNumber()); } public void testExecuteUpdateWithNativeQuery() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final StudentDomain student = JpaTestUtils.getTestStudent(); ExpressionEvaluatingParameterSourceFactory requestParameterSourceFactory = new ExpressionEvaluatingParameterSourceFactory(mock(BeanFactory.class)); ParameterSource source = requestParameterSourceFactory.createParameterSource(student); int updatedRecords = jpaOperations.executeUpdateWithNativeQuery("update Student " + "set lastName = :lastName, lastUpdated = :lastUpdated " + "where rollNumber in (select max(a.rollNumber) from Student a)", source); entityManager.flush(); Assert.assertTrue(1 == updatedRecords); Assert.assertNull(student.getRollNumber()); } public void testExecuteSelectWithNativeQueryReturningEntityClass() throws ParseException { final JpaOperations jpaOperations = getJpaOperations(entityManager); String selectSqlQuery = "select * from Student where lastName = 'Last One'"; Class<?> entityClass = StudentDomain.class; List<?> students = jpaOperations.getResultListForNativeQuery(selectSqlQuery, entityClass, null, 0, 0); Assert.assertTrue(students.size() == 1); StudentDomain retrievedStudent = (StudentDomain) students.iterator().next(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd"); assertEquals(formatter.parse("1980/01/01"), retrievedStudent.getDateOfBirth()); assertEquals("First One", retrievedStudent.getFirstName()); assertEquals(Gender.MALE, retrievedStudent.getGender()); assertEquals("Last One", retrievedStudent.getLastName()); assertNotNull(retrievedStudent.getLastUpdated()); } public void testExecuteSelectWithNativeQuery() throws ParseException { final JpaOperations jpaOperations = getJpaOperations(entityManager); String selectSqlQuery = "select rollNumber, firstName, lastName, gender, dateOfBirth, lastUpdated " + "from Student where lastName = 'Last One'"; List<?> students = jpaOperations.getResultListForNativeQuery(selectSqlQuery, null, null, 0, 0); Assert.assertTrue(students.size() == 1); Object[] retrievedStudent = (Object[]) students.iterator().next(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd"); assertNotNull(retrievedStudent[0]); assertEquals("First One", retrievedStudent[1]); assertEquals("Last One", retrievedStudent[2]); assertEquals("M", retrievedStudent[3]); assertEquals(formatter.parse("1980/01/01"), retrievedStudent[4]); assertNotNull(retrievedStudent[5]); } public void testExecuteUpdateWithNativeNamedQuery() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final StudentDomain student = JpaTestUtils.getTestStudent(); ParameterSourceFactory requestParameterSourceFactory = new ExpressionEvaluatingParameterSourceFactory(mock(BeanFactory.class)); ParameterSource source = requestParameterSourceFactory.createParameterSource(student); int updatedRecords = jpaOperations.executeUpdateWithNamedQuery("updateStudentNativeQuery", source); entityManager.flush(); Assert.assertTrue(1 == updatedRecords); Assert.assertNull(student.getRollNumber()); } /** * Test method for {@link org.springframework.integration.jpa.core.DefaultJpaOperations#merge(java.lang.Object)}. */ public void testMerge() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final StudentDomain student = JpaTestUtils.getTestStudent(); Assert.assertNull(student.getRollNumber()); final StudentDomain savedStudent = (StudentDomain) jpaOperations.merge(student); entityManager.flush(); Assert.assertNull(student.getRollNumber()); Assert.assertNotNull(savedStudent); Assert.assertNotNull(savedStudent.getRollNumber()); Assert.assertTrue(student != savedStudent); } public void testMergeCollection() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final StudentDomain student1 = JpaTestUtils.getTestStudent(); final StudentDomain student2 = JpaTestUtils.getTestStudent(); final StudentDomain student3 = JpaTestUtils.getTestStudent(); student1.setFirstName("Karl"); student2.setFirstName("Otto"); student3.setFirstName("Wilhelm"); List<StudentDomain> students = new ArrayList<StudentDomain>(3); students.add(student1); students.add(student2); students.add(student3); Assert.assertNull(student1.getRollNumber()); Assert.assertNull(student2.getRollNumber()); Assert.assertNull(student3.getRollNumber()); Object savedStudents = jpaOperations.merge(students, 10, true); Assert.assertTrue(savedStudents instanceof List<?>); @SuppressWarnings("unchecked") List<StudentDomain> savedStudentCollection = (List<StudentDomain>) savedStudents; Assert.assertNotNull(savedStudentCollection.get(0).getRollNumber()); Assert.assertNotNull(savedStudentCollection.get(1).getRollNumber()); Assert.assertNotNull(savedStudentCollection.get(2).getRollNumber()); } public void testMergeNullCollection() { final JpaOperations jpaOperations = getJpaOperations(entityManager); try { jpaOperations.merge(null); } catch (IllegalArgumentException e) { Assert.assertEquals("The object to merge must not be null.", e.getMessage()); return; } Assert.fail("Expected an IllegalArgumentException to be thrown."); } public void testMergeCollectionWithNullElement() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final List<?> studentsFromDbBeforeTest = jpaOperations.getResultListForClass(StudentDomain.class, 0, 0); Assert.assertEquals(3, studentsFromDbBeforeTest.size()); final StudentDomain student1 = JpaTestUtils.getTestStudent(); final StudentDomain student2 = null; final StudentDomain student3 = JpaTestUtils.getTestStudent(); student1.setFirstName("Karl"); student3.setFirstName("Wilhelm"); List<StudentDomain> students = new ArrayList<StudentDomain>(3); students.add(student1); students.add(student2); students.add(student3); Assert.assertNull(student1.getRollNumber()); Assert.assertNull(student2); Assert.assertNull(student3.getRollNumber()); Object savedStudents = jpaOperations.merge(students); entityManager.flush(); Assert.assertTrue(savedStudents instanceof List<?>); @SuppressWarnings("unchecked") List<StudentDomain> savedStudentCollection = (List<StudentDomain>) savedStudents; Assert.assertNotNull(savedStudentCollection.get(0).getRollNumber()); Assert.assertNotNull(savedStudentCollection.get(1).getRollNumber()); } /** * Test method for {@link org.springframework.integration.jpa.core.DefaultJpaOperations#persist(java.lang.Object)}. */ public void testPersist() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final StudentDomain student = JpaTestUtils.getTestStudent(); Assert.assertNull(student.getRollNumber()); jpaOperations.persist(student, 1, false); Assert.assertNotNull(student.getRollNumber()); assertTrue(entityManager.contains(student)); } public void testPersistCollection() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final StudentDomain student1 = JpaTestUtils.getTestStudent(); final StudentDomain student2 = JpaTestUtils.getTestStudent(); final StudentDomain student3 = JpaTestUtils.getTestStudent(); student1.setFirstName("Karl"); student2.setFirstName("Otto"); student3.setFirstName("Wilhelm"); List<StudentDomain> students = new ArrayList<StudentDomain>(3); students.add(student1); students.add(student2); students.add(student3); Assert.assertNull(student1.getRollNumber()); Assert.assertNull(student2.getRollNumber()); Assert.assertNull(student3.getRollNumber()); jpaOperations.persist(students, 1, true); Assert.assertNotNull(student1.getRollNumber()); Assert.assertNotNull(student2.getRollNumber()); Assert.assertNotNull(student3.getRollNumber()); assertFalse(entityManager.contains(student1)); assertFalse(entityManager.contains(student2)); assertFalse(entityManager.contains(student3)); } public void testPersistNullCollection() { final JpaOperations jpaOperations = getJpaOperations(entityManager); try { jpaOperations.persist(null); } catch (IllegalArgumentException e) { Assert.assertEquals("The object to persist must not be null.", e.getMessage()); return; } Assert.fail("Expected an IllegalArgumentException to be thrown."); } public void testPersistCollectionWithNullElement() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final List<?> studentsFromDbBeforeTest = jpaOperations.getResultListForClass(StudentDomain.class, 0, 0); Assert.assertEquals(3, studentsFromDbBeforeTest.size()); final StudentDomain student1 = JpaTestUtils.getTestStudent(); final StudentDomain student2 = null; final StudentDomain student3 = JpaTestUtils.getTestStudent(); student1.setFirstName("Karl"); student3.setFirstName("Wilhelm"); List<StudentDomain> students = new ArrayList<StudentDomain>(3); students.add(student1); students.add(student2); students.add(student3); Assert.assertNull(student1.getRollNumber()); Assert.assertNull(student2); Assert.assertNull(student3.getRollNumber()); jpaOperations.persist(students, 10, false); Assert.assertNotNull(student1.getRollNumber()); Assert.assertNotNull(student3.getRollNumber()); final List<?> studentsFromDb = jpaOperations.getResultListForClass(StudentDomain.class, 0, 0); Assert.assertNotNull(studentsFromDb); Assert.assertEquals(5, studentsFromDb.size()); } public void testDeleteInBatch() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final List<?> students = jpaOperations.getResultListForClass(StudentDomain.class, 0, 0); Assert.assertNotNull(students); DefaultTransactionDefinition def = new DefaultTransactionDefinition(); // explicitly setting the transaction name is something that can only be done programmatically def.setName("SomeOtherTxName"); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status = transactionManager.getTransaction(def); jpaOperations.deleteInBatch(students); entityManager.flush(); transactionManager.commit(status); final List<?> studentsFromDb = jpaOperations.getResultListForClass(StudentDomain.class, 0, 0); Assert.assertNotNull(studentsFromDb); Assert.assertTrue(studentsFromDb.size() == 0); } protected JpaOperations getJpaOperations(EntityManager entityManager) { final DefaultJpaOperations jpaOperationsImpl = new DefaultJpaOperations(); jpaOperationsImpl.setEntityManager(entityManager); jpaOperationsImpl.afterPropertiesSet(); return jpaOperationsImpl; } public void testDelete() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final List<?> studentsFromDb = jpaOperations.getResultListForClass(StudentDomain.class, 0, 0); Assert.assertNotNull(studentsFromDb); Assert.assertTrue(studentsFromDb.size() == 3); final StudentDomain student = jpaOperations.find(StudentDomain.class, 1001L); Assert.assertNotNull(student); DefaultTransactionDefinition def = new DefaultTransactionDefinition(); // explicitly setting the transaction name is something that can only be done programmatically def.setName("SomeOtherTxName"); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status = transactionManager.getTransaction(def); jpaOperations.delete(student); entityManager.flush(); transactionManager.commit(status); final List<?> studentsFromDbAfterDelete = jpaOperations.getResultListForClass(StudentDomain.class, 0, 0); Assert.assertNotNull(studentsFromDbAfterDelete); Assert.assertTrue(studentsFromDbAfterDelete.size() == 2); } public void testDeleteInBatchWithEmptyCollection() { final JpaOperations jpaOperations = getJpaOperations(entityManager); final List<?> students = jpaOperations.getResultListForClass(StudentDomain.class, 0, 0); Assert.assertNotNull(students); Assert.assertTrue(students.size() == 3); DefaultTransactionDefinition def = new DefaultTransactionDefinition(); // explicitly setting the transaction name is something that can only be done programmatically def.setName("SomeOtherTxName"); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status = transactionManager.getTransaction(def); jpaOperations.deleteInBatch(new ArrayList<StudentDomain>(0)); entityManager.flush(); transactionManager.commit(status); final List<?> studentsFromDb = jpaOperations.getResultListForClass(StudentDomain.class, 0, 0); Assert.assertNotNull(studentsFromDb); Assert.assertTrue(studentsFromDb.size() == 3); //Nothing should have happened } public void testGetAllStudentsFromThirdRecord() { JpaOperations jpaOperations = getJpaOperations(entityManager); List<?> results = jpaOperations.getResultListForClass(StudentDomain.class, 2, 0); assertEquals(1, results.size()); } public void testGetAllStudentsUsingNativeQueryFromThirdRecord() { JpaOperations jpaOperations = getJpaOperations(entityManager); String query = "select * from Student"; List<?> results = jpaOperations.getResultListForNativeQuery(query, StudentDomain.class, null, 2, 0); assertEquals(1, results.size()); } public void testGetAllStudentsUsingNamedQueryFromThirdRecord() { JpaOperations jpaOperations = getJpaOperations(entityManager); List<?> results = jpaOperations.getResultListForNamedQuery("selectAllStudents", null, 2, 0); assertEquals(1, results.size()); } public void testGetAllStudentsUsingJPAQueryFromThirdRecord() { JpaOperations jpaOperations = getJpaOperations(entityManager); String query = "select s from Student s"; List<?> results = jpaOperations.getResultListForQuery(query, null, 2, 0); assertEquals(1, results.size()); } public void testWithNegativeMaxNumberofResults() { JpaOperations jpaOperations = getJpaOperations(entityManager); String query = "select s from Student s"; List<?> results = jpaOperations.getResultListForQuery(query, null, 0, -1); assertEquals(3, results.size()); } }