Java Session.get 方法如何在休眠中工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27896994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How Session.get method works in hibernate
提问by Vinit89
I am trying to understand that how object initialization works for returned object by Session Get method.Please validate my understanding. When it executes, it checks for object with given identifier in the first level cache and then the Second level cache (If it is configured), If not found then fires the select query to retrieve the data from database. My question is, Does it include associations in select query which are configured for lazy loading or null value is set for such associations in returned object?
我试图了解对象初始化如何通过 Session Get 方法对返回的对象起作用。请验证我的理解。当它执行时,它会在一级缓存中检查具有给定标识符的对象,然后在二级缓存(如果已配置)中检查对象,如果未找到,则触发选择查询以从数据库中检索数据。我的问题是,它是否包括选择查询中的关联,这些关联是为延迟加载配置的,还是为返回对象中的此类关联设置了空值?
If this is case then session.get does not do the complete initialization of the returned object which is contradictory to what is written on most of hibernate tutorials available on web.
如果是这种情况,则 session.get 不会对返回的对象进行完整的初始化,这与大多数 web 上可用的 hibernate 教程中所写的内容相矛盾。
采纳答案by Radim K?hler
To answer the question:
要回答这个问题:
Does it include associations in select querywhich are configured for lazy loadingor null value is set for such associations in returned object?
它是否包括选择查询中的关联,这些关联是为延迟加载配置的,还是为返回对象中的此类关联设置了空值?
1) The session.get()
will NOTinitiate lazy stuff. NEVER. In fact that is the central thought of the design. Otherwise - we would be able to load whole DB in one SHOT (in one JAVA call to session.get()
)
1)session.get()
将不发起慵懒的东西。绝不。事实上,这是设计的中心思想。否则 - 我们将能够在一次 SHOT 中加载整个数据库(在一次 JAVA 调用中session.get()
)
2) And also there WILL NOTbe null instead. Each reference or collection will be represented by proxy. This is the way how we can avoid to load compelte DB in one shot (all stuff initialized with one method get). Because each proxy is in fact a promise - once we will touch it... it will load the real data.
2)而且也不会为空。每个引用或集合将由proxy表示。这是我们如何避免一次性加载完整数据库的方式(所有内容都使用一种方法初始化)。因为每个代理实际上都是一个承诺——一旦我们接触它......它就会加载真实的数据。
And so on. So get is very safe way how to recieve as few data as was configured....
等等。所以 get 是一种非常安全的方式来接收尽可能少的数据配置....
回答by Ankur Singhal
Simply
简单地
When get()
method is called, it will directly hit the database, fetch the result and return. If no matching fields are found, it will gladly return null.
当get()
方法被调用时,它会直接命中数据库,获取结果并返回。如果没有找到匹配的字段,它会很乐意返回 null。
Depending on the annotations on references, Lazy or Eager, data will be returned. if Lazy
, proxy will be returned instead of null, if Eager
, fully initialized object will be returned.
根据引用上的注释,Lazy 或 Eager,将返回数据。如果Lazy
,将返回代理而不是空,如果Eager
,将返回完全初始化的对象。
Better to monitor the queries at the backend, for good understanding.
最好在后端监控查询,以便更好地理解。
回答by Manoj Kumar
Hibernate Session provide different methods to fetch data from database. Two of them are – get() and load(). get() returns the object by fetching it from database or from hibernate cache. when we use get() to retrieve data that doesn't exists, it returns null, because it try to load the data as soon as it's called.
Hibernate Session 提供了不同的方法来从数据库中获取数据。其中两个是 – get() 和 load()。get() 通过从数据库或休眠缓存中获取对象来返回对象。当我们使用 get() 检索不存在的数据时,它返回 null,因为它会在调用后立即加载数据。
- We should use get() when we want to make sure data exists in the database.
- 当我们想确保数据库中存在数据时,我们应该使用 get()。
For Example :
例如 :
In a Stock application , Stock and StockTransactions should have a “one-to-many” relationship, when you want to save a stock transaction, it's common to declared something like below.
在 Stock 应用程序中,Stock 和 StockTransactions 应该有“一对多”的关系,当你想保存一个股票交易时,通常会声明如下内容。
Stock stock = (Stock)session.get(Stock.class, new Integer(2));
StockTransaction stockTransactions = new StockTransaction();
//set stockTransactions detail
stockTransactions.setStock(stock);
session.save(stockTransactions);
Output :
输出 :
Hibernate:
select ... from mkyong.stock stock0_
where stock0_.STOCK_ID=?
Hibernate:
insert into mkyong.stock_transaction (...)
values (?, ?, ?, ?, ?, ?)
In session.get(), Hibernate will hit the database to retrieve the Stock object and put it as a reference to StockTransaction.
在 session.get() 中,Hibernate 将访问数据库以检索 Stock 对象并将其作为对 StockTransaction 的引用。
回答by Amitesh Kumar
1) Customer entity class that map the T_CUSTOMER DB table:
1) 映射 T_CUSTOMER 数据库表的客户实体类:
@Entity
@Table(name= “T_CUSTOMER”)
public class Customer {
@Id
@Column (name=“cust_id”)
private Long id;
@OneToMany(fetch=FetchType.EAGER)
@JoinColumn (name=“cid”)
private Set<Address> addresses;
…
…
…
}
2) Address entity class that map the T_ADDRESS DB table:
2)映射T_ADDRESS DB表的地址实体类:
@Entity
@Table(name= “T_ADDRESS”)
public class Address {
// Fields and Properties
}
Consider this Customers table :
考虑这个客户表:
----------------------------------------------------------------------------
| Cust_id | Cust_firstname | Cust_lastname | Cust_email | Cust_mobile |
----------------------------------------------------------------------------
| 101 | XXXX | YYYYY |[email protected] | 8282263131 |
----------------------------------------------------------------------------
The Above customers table is having one record with cust_id as 101.
上述客户表有一个 cust_id 为 101 的记录。
Now Consider this Address Table :
现在考虑这个地址表:
----------------------------------------------------------------------------
| id | street | suburb | city | zipcode | cid |
----------------------------------------------------------------------------
| 1 | streetX | AreaY | cityZ | 54726 | 101 |
----------------------------------------------------------------------------
| 2 | streetXA | AreaYB | cityZS | 60660 | 101 |
----------------------------------------------------------------------------
Now When you invoke :
现在当你调用:
Customer cust = (Customer)session.get(Customer.class, 101);
Then Hibernate will fire a SQL Query Something like :
然后 Hibernate 会触发一个 SQL 查询,例如:
1).In case of EAGER LOADING :
1)。在急切加载的情况下:
SELECT * FROM T_CUSTOMER cust JOIN T_ADDRESS add ON cust.cust_id=add.cid
SELECT * FROM T_CUSTOMER cust JOIN T_ADDRESS add ON cust.cust_id=add.cid
i.e, It will load all the data related to the T_CUSTOMERS table and it's associated tables, which is T_ADDRESS table in this case.
即,它将加载与 T_CUSTOMERS 表及其关联表相关的所有数据,在本例中为 T_ADDRESS 表。
2).I case of LAZY LOADING :
2)。I延迟加载的情况:
SELECT * FROM T_CUSTOMER WHERE cust_id=101;
So, it only fetches the data corresponding to the T_CUSTOMER table and uses Proxy for the T_ADDRESS table as said above by @Radim K?hler. It will fetch the data from the T_ADDRESS TABLE only when you'll call :
因此,它只获取与 T_CUSTOMER 表相对应的数据,并为 T_ADDRESS 表使用代理,如@Radim K?hler 所述。只有当您调用时,它才会从 T_ADDRESS TABLE 中获取数据:
cust.getAddresses();