简体   繁体   中英

Is it a good idea to close and open hibernate sessions frequently?

I'm developing an application which requires that state of entities be read from a database at frequent intervals or triggers. However, once hibernate reads the state, it doesn't re-read it unless I explicitly close the session and read the entity in a new session.

Is it a good idea to open a session everytime I want to read the entity and then close it afterwards? How much of an overhead does this put on the application and the database (we use a c3p0 connection pool also)?

Will it be enough to simply evict the entity from the session before reading it again?

You can also use refresh to reload the entity. Or evict and clear , as mentioned by @Bozho.

With a connection pool, the overhead to open and close session isn't big. What takes time is to construct the session factory.

The problem with closing and re-opening a session is that object already loaded will still become detached, if I remember well. This can be problematic wrt to lazy loading. So it's better to keep the session open and use evict , clear or refresh .

Note that if you evict the entity, and you access one such entity already loaded, you will still get the old data.

MyEntity e = session.load( ... );
...
session.evict(e);         // remove entity from the cache
String p = e.myProperty;  // still the value at the time it was loaded
e = sesssion.load( ... ); // latest value

In you case, it might be better to introduce a design guideline that says that anytime the entity is manipulated, it should be refreshed first.

MyEntity e = session.load( ... );
...
session.refresh( e );     // refresh entity and cache
String p = e.myProperty;  // latest value
e = sesssion.load( ... ); // latest value

The code above is only pseudo-code, I haven't checked it.

Note that if the session is opened for a certain time, the cache may grow, in which case you may want to still clear it. Generally speaking, it's however better to keep the session short to prevent this problem of cache growth, plus problems with connection timeout, transaction timeout, and lock contention.

Yes. evict() the object. If you want to clear the entire session, clear() it.

A new session should be associated with either a request (thread) or a longer-running conversation.

For columns that link to other tables, if you set the fetchtype to LAZY Hibernate won't load that data until it is explicitly asked for. This saves a lot of time.

A column in Table could be marked:

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="other_table_id", nullable = false)
private OtherTable otherTable;

So, not until you do something like Table.getOtherTable().getValue() will the OtherTable be loaded into the session. So if you don't do something that, you also don't need to evict it.

Please note that this is pseudocodish and might look a little different for your program.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM