diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java index a4d7c30e2c..1d0b8da8ab 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java @@ -495,6 +495,8 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana if (definition.isReadOnly() && txObject.isNewSession()) { // Just set to MANUAL in case of a new Session for this transaction. session.setFlushMode(FlushMode.MANUAL); + // As of 5.1, we're also setting Hibernate's read-only entity mode by default. + session.setDefaultReadOnly(true); } if (!definition.isReadOnly() && !txObject.isNewSession()) { diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests.java index f6d688f01f..fd3d5b73a2 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/orm/HibernateSessionFlushingTests.java @@ -18,6 +18,7 @@ package org.springframework.test.context.junit4.orm; import javax.persistence.PersistenceException; +import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.exception.ConstraintViolationException; import org.junit.Before; @@ -29,6 +30,7 @@ import org.springframework.test.context.junit4.AbstractTransactionalJUnit4Spring import org.springframework.test.context.junit4.orm.domain.DriversLicense; import org.springframework.test.context.junit4.orm.domain.Person; import org.springframework.test.context.junit4.orm.service.PersonService; +import org.springframework.transaction.annotation.Transactional; import static org.junit.Assert.*; import static org.springframework.test.transaction.TransactionTestUtils.*; @@ -38,6 +40,8 @@ import static org.springframework.test.transaction.TransactionTestUtils.*; * Hibernate. * * @author Sam Brannen + * @author Juergen Hoeller + * @author Vlad Mihalcea * @since 3.0 */ @ContextConfiguration @@ -53,21 +57,14 @@ public class HibernateSessionFlushingTests extends AbstractTransactionalJUnit4Sp private SessionFactory sessionFactory; - protected int countRowsInPersonTable() { - return countRowsInTable("person"); - } - - protected void assertPersonCount(int expectedCount) { - assertEquals("Verifying number of rows in the 'person' table.", expectedCount, countRowsInPersonTable()); - } - @Before - public void setUp() { + public void setup() { assertInTransaction(true); assertNotNull("PersonService should have been autowired.", personService); assertNotNull("SessionFactory should have been autowired.", sessionFactory); } + @Test public void findSam() { Person sam = personService.findByName(SAM); @@ -77,13 +74,25 @@ public class HibernateSessionFlushingTests extends AbstractTransactionalJUnit4Sp assertEquals("Verifying Sam's driver's license number", Long.valueOf(1234), driversLicense.getNumber()); } + @Test // SPR-16956 + @Transactional(readOnly = true) + public void findSamWithReadOnlySession() { + Person sam = personService.findByName(SAM); + sam.setName("Vlad"); + // By setting setDefaultReadOnly(true), the user can no longer modify any entity... + Session session = sessionFactory.getCurrentSession(); + session.flush(); + session.refresh(sam); + assertEquals("Sam", sam.getName()); + } + @Test public void saveJuergenWithDriversLicense() { DriversLicense driversLicense = new DriversLicense(2L, 2222L); Person juergen = new Person(JUERGEN, driversLicense); - int numRows = countRowsInPersonTable(); + int numRows = countRowsInTable("person"); personService.save(juergen); - assertPersonCount(numRows + 1); + assertEquals("Verifying number of rows in the 'person' table.", numRows + 1, countRowsInTable("person")); assertNotNull("Should be able to save and retrieve Juergen", personService.findByName(JUERGEN)); assertNotNull("Juergen's ID should have been set", juergen.getId()); } @@ -93,13 +102,6 @@ public class HibernateSessionFlushingTests extends AbstractTransactionalJUnit4Sp personService.save(new Person(JUERGEN)); } - private void updateSamWithNullDriversLicense() { - Person sam = personService.findByName(SAM); - assertNotNull("Should be able to find Sam", sam); - sam.setDriversLicense(null); - personService.save(sam); - } - @Test // no expected exception! public void updateSamWithNullDriversLicenseWithoutSessionFlush() { @@ -121,4 +123,11 @@ public class HibernateSessionFlushingTests extends AbstractTransactionalJUnit4Sp } } + private void updateSamWithNullDriversLicense() { + Person sam = personService.findByName(SAM); + assertNotNull("Should be able to find Sam", sam); + sam.setDriversLicense(null); + personService.save(sam); + } + }