问题
Theoretically, session.get() method is supposed to hit the database always, no matter whether the entity is stored in the cache or not. But whenever I use session.get() or session.load(), both doesn't hit the database second time.
Session session = factory.openSession();
tx = session.beginTransaction();
Customer cust = (Customer)session.get(Customer.class,2);
System.out.println(cust.getCid()+","+cust.getFirstName()+","+cust.getLastName()+","+cust.getPhone());
Customer cust2 = (Customer)session.get(Customer.class,2);
System.out.println(cust2.getCid()+","+cust2.getFirstName()+","+cust2.getLastName()+","+cust2.getPhone());
tx.commit();
session.close();
and this is the output,
Hibernate: select customer0_.cid as cid1_1_0_, customer0_.firstName as firstNam2_1_0_, customer0_.lastName as lastName3_1_0_, customer0_.email as email4_1_0_, customer0_.phone as phone5_1_0_, customer0_.aid as aid6_1_0_ from mycustomers customer0_ where customer0_.cid=?
2,Sam,pp,9799999999
2,Sam,pp,9799999999
Select query is executed only once and next time, it's retrieved from the cache. Same output if I use session.load() method also.
Am I missing something here? Please clarify.
回答1:
Here's what's happening here:
The first query on console
It will always return a “proxy”. For example if you do
session.load(Customer.class, 2)
, it will return a proxy object. Proxy object just have an identifier value and nothing else. You can imagine it to be somewhat like this.customer.id = 2; customer.fname = null; customer.lname = null; customer.address = null; //rest all properties are null
It will Hit the database whenever you'll access the properties. In your case you're immediately calling
ust.getCid()
so it will immediately hit the database to fetch those queries. So the first query that you see in your console will appear for both the cases (i.e.,session.get()
andsession.load()
)Try doing this and see what your console looks like:
Session session = factory.openSession(); tx = session.beginTransaction(); Customer cust = (Customer)session.get(Customer.class,2); //do not call any getter.
You'll see the difference on your console.
Why is second query not appearing
Hibernate Second Level Cache
You're trying to access the same object that you've accessed previously. Hibernate will then (instead of fetching it from database again) fetch it from second level cache.You'll find detailed example of this scenario on this page : Hibernate Second Level Cache. (just see the last example, it's similar to what you're getting)
来源:https://stackoverflow.com/questions/42571072/doesnt-session-get-in-hibernate-always-hit-the-database