下面列出了org.hibernate.Session#flush ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public void testUpdateFalse() {
getSessions().getStatistics().clear();
Session s = openSession();
Transaction t = s.beginTransaction();
User u = new User( "gavin", "secret", new Person("Gavin King", new Date(), "Karbarook Ave") );
s.persist(u);
s.flush();
u.getPerson().setName("XXXXYYYYY");
t.commit();
s.close();
assertEquals( 1, getSessions().getStatistics().getEntityInsertCount() );
assertEquals( 0, getSessions().getStatistics().getEntityUpdateCount() );
s = openSession();
t = s.beginTransaction();
u = (User) s.get(User.class, "gavin");
assertEquals( u.getPerson().getName(), "Gavin King" );
s.delete(u);
t.commit();
s.close();
assertEquals( 1, getSessions().getStatistics().getEntityDeleteCount() );
}
public void testNaturalIdCheck() throws Exception {
Session s = openSession();
Transaction t = s.beginTransaction();
User u = new User("gavin", "hb", "secret");
s.persist(u);
Field name = u.getClass().getDeclaredField("name");
name.setAccessible(true);
name.set(u, "Gavin");
try {
s.flush();
fail();
}
catch (HibernateException he) {}
name.set(u, "gavin");
s.delete(u);
t.commit();
s.close();
}
public void testInsertionFailureWithExceptionChecking() {
Session s = openSession();
s.beginTransaction();
ExceptionCheckingEntity e = new ExceptionCheckingEntity();
e.setName( "dummy" );
s.save( e );
try {
s.flush();
fail( "expection flush failure!" );
}
catch( JDBCException ex ) {
// these should specifically be JDBCExceptions...
}
s.clear();
s.getTransaction().commit();
s.close();
}
/** {@inheritDoc} */
@Override public void onSessionEnd(CacheStoreSession ses, boolean commit) {
Session hibSes = ses.attach(null);
if (hibSes != null) {
try {
Transaction tx = hibSes.getTransaction();
if (commit) {
if (hibSes.isDirty())
hibSes.flush();
if (tx.getStatus() == TransactionStatus.ACTIVE)
tx.commit();
}
else if (tx.getStatus().canRollback())
tx.rollback();
}
catch (HibernateException e) {
throw new CacheWriterException("Failed to end store session [tx=" + ses.transaction() + ']', e);
}
finally {
hibSes.close();
}
}
}
/**
* Should use hibernate orm 52.
*/
@Test
@Transactional(value=TransactionMode.ROLLBACK)
public void shouldUseHibernateOrm52() {
Session session = entityManager.unwrap( Session.class );
Kryptonite kryptonite1 = new Kryptonite();
kryptonite1.id = 1L;
kryptonite1.description = "Some Kryptonite";
session.persist( kryptonite1 );
session.flush();
session.clear();
// EntityManager methods exposed through Session only as of 5.2
Kryptonite loaded = session.find( Kryptonite.class, 1L );
assertThat( loaded.description, equalTo( "Some Kryptonite" ) );
}
public void testSuppliedConnection() throws Throwable {
prepare();
Connection originalConnection = DummyTransactionManager.INSTANCE.getCurrent().getConnection();
Session session = getSessions().openSession( originalConnection );
Silly silly = new Silly( "silly" );
session.save( silly );
// this will cause the connection manager to cycle through the aggressive release logic;
// it should not release the connection since we explicitly suplied it ourselves.
session.flush();
assertTrue( "Different connections", originalConnection == session.connection() );
session.delete( silly );
session.flush();
release( session );
done();
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW, isolation = Isolation.REPEATABLE_READ)
public void internalUndelete(final O obj)
{
final O dbObj = getHibernateTemplate().load(clazz, obj.getId(), LockMode.PESSIMISTIC_WRITE);
onSaveOrModify(obj);
copyValues(obj, dbObj, "deleted"); // If user has made additional changes.
dbObj.setDeleted(false);
obj.setDeleted(false);
dbObj.setLastUpdate();
obj.setLastUpdate(dbObj.getLastUpdate());
log.info("Object undeleted: " + dbObj.toString());
final Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
session.flush();
Search.getFullTextSession(session).flushToIndexes();
afterSaveOrModify(obj);
afterUndelete(obj);
}
@Override
public void updateNonDefaultI18NMessagesLabel(SbiI18NMessages oldMessage, SbiI18NMessages newMessage) {
logger.debug("IN");
Session session = null;
Transaction tx = null;
try {
session = getSession();
tx = session.beginTransaction();
String tenant = getTenant();
List<SbiI18NMessages> messages = getSbiI18NMessagesByLabel(oldMessage, tenant, session);
Iterator<SbiI18NMessages> it = messages.iterator();
while (it.hasNext()) {
SbiI18NMessages toModify = it.next();
toModify.setLabel(newMessage.getLabel());
updateSbiCommonInfo4Update(toModify);
session.update(toModify);
session.flush();
}
tx.commit();
} catch (HibernateException e) {
logException(e);
if (tx != null)
tx.rollback();
throw new RuntimeException();
} finally {
if (session != null) {
if (session.isOpen())
session.close();
}
}
logger.debug("OUT");
}
public void testSimpleRollback() {
Session session = openSession();
Transaction t = session.beginTransaction();
Product prod = new Product();
assertNull( prod.getName() );
session.persist(prod);
session.flush();
assertNotNull( prod.getName() );
t.rollback();
session.close();
}
@Test
public void testTimeToLive() throws InterruptedException {
Statistics stats = sessionFactory().getStatistics();
Long id = null;
Session s = openSession();
s.beginTransaction();
ItemReadWrite item = new ItemReadWrite( "data" );
id = (Long) s.save( item );
s.flush();
s.getTransaction().commit();
s.close();
Thread.sleep(900);
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
Assert.assertEquals("data", item.getName());
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(0, stats.getSecondLevelCacheStatistics("item").getMissCount());
Thread.sleep(600);
s = openSession();
s.beginTransaction();
item = (ItemReadWrite) s.get(ItemReadWrite.class, id);
Assert.assertEquals("data", item.getName());
s.delete(item);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getHitCount());
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("item").getMissCount());
}
/**
* Actually writes data to database (once transaction closed).
* Uses Hibernate batching so don't use as much memory.
* @param object
*/
private void writeObject(Session session, Object object) {
session.saveOrUpdate(object);
// Since can writing large amount of data should use Hibernate
// batching to make sure don't run out memory.
counter++;
if (counter % HibernateUtils.BATCH_SIZE == 0) {
session.flush();
session.clear();
}
}
@Timed
public void createEntity(String name, String value) {
final Session session = sf.openSession();
session.save(new Entity(name, value));
session.flush();
}
/**
* Util to reload an object from the DB using Hibernate.
* @param objClass of object being looked up
* @param id of object
* @param <T> type of object to reload
* @return Object found or NULL if not
* @throws HibernateException if something goes wrong.
*/
public static <T> T reload(Class<T> objClass, Serializable id)
throws HibernateException {
Session session = HibernateFactory.getSession();
session.flush();
/*
* In hibernate 3, the following doesn't work:
* Object obj = session.load(objClass, id);
* load returns the proxy class instead of the persisted class, ie,
* Filter$$EnhancerByCGLIB$$9bcc734d_2 instead of Filter.
* session.get is set to not return the proxy class, so that is what we'll use.
*/
T obj = (T)session.get(objClass, id);
return reload(obj);
}
public void save(T entity) {
Session session = getSession();
Transaction transaction = session.beginTransaction();
session.save(entity);
session.flush();
transaction.commit();
}
@Override
public void insertI18NMessage(SbiI18NMessageBody message) {
logger.debug("IN");
Session session = null;
Transaction tx = null;
SbiI18NMessages toInsert = new SbiI18NMessages();
try {
session = getSession();
tx = session.beginTransaction();
Integer domainId = getSbiDomainId(message.getLanguage(), session);
toInsert.setLanguageCd(domainId);
toInsert.setLabel(message.getLabel());
toInsert.setMessage(message.getMessage());
updateSbiCommonInfo4Insert(toInsert);
session.save(toInsert);
tx.commit();
session.flush();
} catch (HibernateException e) {
logException(e);
if (tx != null)
tx.rollback();
throw new RuntimeException();
} finally {
if (session != null) {
if (session.isOpen())
session.close();
}
}
logger.debug("OUT");
}
/**
* Persists all the given entities into the DB configured in the {@code SessionFactory}. Specify
* the following system properties backoff.delay
*/
@Override
@Transactional
@Retryable(
value = {LockAcquisitionException.class},
maxAttemptsExpression = "#{ @systemProperties['retryBackoff'] ?: 20}",
backoff =
@Backoff(
delayExpression = "#{ @systemProperties['retryDelay'] ?: 100}",
maxDelayExpression = "#{ @systemProperties['retryMaxDelay'] ?: 50000 }",
multiplierExpression = "#{ @systemProperties['retryMultiplier'] ?: 1.5}"))
public void persistReportEntities(List<? extends Report> reportEntities) {
int batchFlush = 0;
Session session = sessionFactory.getCurrentSession();
FlushMode previousFlushMode = session.getHibernateFlushMode();
session.setHibernateFlushMode(FlushMode.MANUAL);
try {
for (Report report : reportEntities) {
report.setRowId();
session.saveOrUpdate(report);
batchFlush++;
if (batchFlush == config.getBatchSize()) {
session.flush();
session.clear();
batchFlush = 0;
}
}
if (batchFlush > 0) {
session.flush();
session.clear();
}
} catch (NonUniqueObjectException ex) {
// Github issue 268 & 280
// https://github.com/googleads/aw-reporting/issues/268
// https://github.com/googleads/aw-reporting/issues/280
//
// Currently we allow specifying report definitions which do not include all primary key
// fields. This leads to cryptic hibernate errors without providing a reasonable
// resolution strategy.
//
// This fix explains where to find the list of primary key fields, but does not address
// the underlying issue of allowing non-unique rows to be downloaded in the first place.
//
// Ideally we would guarantee uniqueness of rows without the user having to specify the
// PK fields.
// However, this would be a substantial migration for the AWReporting user base.
// Instead, we just log a (hopefully) useful error message.
// Also note that the error message assumes that reportEntities was not empty, because
// otherwise the exception would not have been thrown.
logger.error(
"Duplicate row detected. This is most likely because your report definition does not "
+ "include the primary key fields defined in {}.setRowId(). "
+ "Please add the missing fields and try again.",
reportEntities.get(0).getClass().getName());
throw ex;
} finally {
session.setHibernateFlushMode(previousFlushMode);
}
}
private TrackerTypeReport handleEvents( Session session, TrackerBundle bundle )
{
List<Event> events = bundle.getEvents();
TrackerTypeReport typeReport = new TrackerTypeReport( TrackerType.EVENT );
events.forEach( o -> bundleHooks.forEach( hook -> hook.preCreate( Event.class, o, bundle ) ) );
session.flush();
for ( int idx = 0; idx < events.size(); idx++ )
{
Event event = events.get( idx );
ProgramStageInstance programStageInstance = eventTrackerConverterService.from( bundle.getPreheat(), event );
TrackerObjectReport objectReport = new TrackerObjectReport( TrackerType.EVENT,
programStageInstance.getUid(), idx );
typeReport.addObjectReport( objectReport );
Date now = new Date();
if ( bundle.getImportStrategy().isCreate() )
{
programStageInstance.setCreated( now );
programStageInstance.setCreatedAtClient( now );
}
programStageInstance.setLastUpdated( now );
programStageInstance.setLastUpdatedAtClient( now );
programStageInstance.setLastUpdatedBy( bundle.getUser() );
session.persist( programStageInstance );
bundle.getPreheat().putEvents( bundle.getIdentifier(), Collections.singletonList( programStageInstance ) );
typeReport.getStats().incCreated();
if ( FlushMode.OBJECT == bundle.getFlushMode() )
{
session.flush();
}
TrackerSideEffectDataBundle sideEffectDataBundle = TrackerSideEffectDataBundle.builder()
.klass( ProgramStageInstance.class )
.enrollmentRuleEffects( bundle.getEnrollmentRuleEffects() )
.eventRuleEffects( bundle.getEventRuleEffects() )
.object( programStageInstance )
.importStrategy( bundle.getImportStrategy() )
.accessedBy( bundle.getUsername() )
.build();
sideEffectHandlers.forEach( handler -> handler.handleSideEffect( sideEffectDataBundle ) );
}
session.flush();
events.forEach( o -> bundleHooks.forEach( hook -> hook.postCreate( Event.class, o, bundle ) ) );
return typeReport;
}
@Test
public void testQuery() {
Statistics stats = sessionFactory().getStatistics();
Session s = openSession();
s.beginTransaction();
A a = new A();
a.id = 1L;
a.uniqueField = "1";
B b = new B();
b.id = 1L;
s.save(b);
a.bs.add(b);
s.save(a);
s.flush();
s.getTransaction().commit();
s = openSession();
s.beginTransaction();
A a1 = s.get(A.class, 1L);
System.out.println("here1");
assertThat(a1.bs).hasSize(1);
s.getTransaction().commit();
Assert.assertEquals(0, stats.getSecondLevelCacheStatistics("org.redisson.hibernate.CollectionTest$A.bs").getHitCount());
s = openSession();
s.beginTransaction();
A a2 = s.get(A.class, 1L);
B b2 = a2.bs.iterator().next();
assertThat(a2.bs.size()).isEqualTo(1);
s.getTransaction().commit();
s.close();
Assert.assertEquals(1, stats.getSecondLevelCacheStatistics("org.redisson.hibernate.CollectionTest$A.bs").getHitCount());
stats.logSummary();
}
/**
* Test the equivalent of EJB3 LockModeType.READ
* <p/>
* From the spec:
* <p/>
* If transaction T1 calls lock(entity, LockModeType.READ) on a versioned object, the entity
* manager must ensure that neither of the following phenomena can occur:<ul>
* <li>P1 (Dirty read): Transaction T1 modifies a row. Another transaction T2 then reads that row and
* obtains the modified value, before T1 has committed or rolled back. Transaction T2 eventually
* commits successfully; it does not matter whether T1 commits or rolls back and whether it does
* so before or after T2 commits.
* <li>P2 (Non-repeatable read): Transaction T1 reads a row. Another transaction T2 then modifies or
* deletes that row, before T1 has committed. Both transactions eventually commit successfully.
* <p/>
* This will generally be achieved by the entity manager acquiring a lock on the underlying database row.
* Any such lock may be obtained immediately (so long as it is retained until commit completes), or the
* lock may be deferred until commit time (although even then it must be retained until the commit completes).
* Any implementation that supports repeatable reads in a way that prevents the above phenomena
* is permissible.
* <p/>
* The persistence implementation is not required to support calling lock(entity, LockMode-Type.READ)
* on a non-versioned object. When it cannot support such a lock call, it must throw the
* PersistenceException. When supported, whether for versioned or non-versioned objects, LockMode-Type.READ
* must always prevent the phenomena P1 and P2. Applications that call lock(entity, LockModeType.READ)
* on non-versioned objects will not be portable.
* <p/>
* Odd as it may sound, EJB3 LockModeType.READ actually maps to the Hibernate LockMode.UPGRADE
*/
public void testLockModeTypeRead() {
if ( ! readCommittedIsolationMaintained( "ejb3 lock tests" ) ) {
return;
}
if ( getDialect().doesReadCommittedCauseWritersToBlockReaders() ) {
reportSkip( "write locks block readers", "jpa read locking" );
return;
}
final String initialName = "lock test";
// set up some test data
Session s1 = getSessions().openSession();
Transaction t1 = s1.beginTransaction();
Item item = new Item();
item.setName( initialName );
s1.save( item );
t1.commit();
s1.close();
Long itemId = item.getId();
// perform the isolated update
s1 = getSessions().openSession();
t1 = s1.beginTransaction();
item = ( Item ) s1.get( Item.class, itemId );
s1.lock( item, LockMode.UPGRADE );
item.setName( "updated" );
s1.flush();
Session s2 = getSessions().openSession();
Transaction t2 = s2.beginTransaction();
Item item2 = ( Item ) s2.get( Item.class, itemId );
assertEquals( "isolation not maintained", initialName, item2.getName() );
t1.commit();
s1.close();
item2 = ( Item ) s2.get( Item.class, itemId );
assertEquals( "repeatable read not maintained", initialName, item2.getName() );
t2.commit();
s2.close();
s1 = getSessions().openSession();
t1 = s1.beginTransaction();
s1.delete( item );
t1.commit();
s1.close();
}
@Test
@Commit
public void givenTransactionCommitDefault_whenProgrammaticTransactionCommit_thenEntityIsInDatabase() {
assertTrue(TestTransaction.isActive());
//Save an entity and commit.
Session session = sessionFactory.getCurrentSession();
TestEntity newEntity = new TestEntity();
newEntity.setId(1);
session.save(newEntity);
TestEntity searchEntity = session.find(TestEntity.class, 1);
Assert.assertNotNull(searchEntity);
assertFalse(TestTransaction.isFlaggedForRollback());
TestTransaction.end();
assertFalse(TestTransaction.isFlaggedForRollback());
assertFalse(TestTransaction.isActive());
//Check that the entity is still there in a new transaction,
//then delete it, but don't commit.
TestTransaction.start();
assertFalse(TestTransaction.isFlaggedForRollback());
assertTrue(TestTransaction.isActive());
session = sessionFactory.getCurrentSession();
searchEntity = session.find(TestEntity.class, 1);
Assert.assertNotNull(searchEntity);
session.delete(searchEntity);
session.flush();
TestTransaction.flagForRollback();
TestTransaction.end();
assertFalse(TestTransaction.isActive());
//Check that the entity is still there in a new transaction,
//then delete it and commit.
TestTransaction.start();
session = sessionFactory.getCurrentSession();
searchEntity = session.find(TestEntity.class, 1);
Assert.assertNotNull(searchEntity);
session.delete(searchEntity);
session.flush();
assertTrue(TestTransaction.isActive());
TestTransaction.end();
assertFalse(TestTransaction.isActive());
//Check that the entity is no longer there in a new transaction.
TestTransaction.start();
assertTrue(TestTransaction.isActive());
session = sessionFactory.getCurrentSession();
searchEntity = session.find(TestEntity.class, 1);
Assert.assertNull(searchEntity);
}