Java 休眠会话的 get() 和 load() 方法在获取方面有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22142920/
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
What is difference between get() and load() method of hibernate session with respect to fetching?
提问by sar
What is difference between get () and load() method? with respect to data fetching approach
get() 和 load() 方法有什么区别?关于数据获取方法
public static void main(String[] args) {
SessionFactory factory= new Configuration().configure().buildSessionFactory();
Session session = factory.openSession();
Transaction tx = null;
tx = session.beginTransaction();
System.out.println("1 st time calling load method");
Account acc =
(Account)session.load(Account.class, 180);
System.out.println("bal"+acc.getBalance());
System.out.println("2nd time calling load method");
Account acc1=(Account)session.load(Account.class, 180);
System.out.println("bal"+acc1.getBalance());
System.out.println("1 st time calling get method");
Account acc2= (Account) session.get(Account.class, accId);
System.out.println("bal"+acc2.getBalance());
System.out.println("2 st time calling get method");
Account acc2= (Account) session.get(Account.class, accId);
System.out.println("bal"+acc2.getBalance());
tx.commit();
session.close();
}
}
I got following output
我得到以下输出
1 st time calling load method
Hibernate:
/* load com.abcd.Account */ select
account0_.ACCOUNTID as ACCOUNTID1_0_,
account0_.ACCOUNTTYPE as ACCOUNTT2_1_0_,
account0_.CREATIONDATE as CREATION3_1_0_,
account0_.BALANCE as BALANCE1_0_
from
a.MYACCOUNT account0_
where
account0_.ACCOUNTID=?
bal3000.0
2nd time calling load method
bal3000.0
1 st time calling get method
bal3000.0
2 st time calling get method
bal3000.0
From ouput it is clear that get method did not hit database.It behaves like load() method. Could any one tell me is this behavior correct.
从输出可以看出 get 方法没有命中数据库。它的行为类似于 load() 方法。谁能告诉我这种行为是否正确。
采纳答案by Engineer
As T Mishra states here:
为T米什拉指出这里:
By default, hibernate creates run-time proxies. It loads the objects as a proxy unless a fetch mode is specified or set to false.
That's because once the object is loaded in cache, the next subsequent calls perform repeatable read.
- Although the state of this object changes from persistent to detached
The entity can be retrieved in 2 ways.
load() - returns the proxy object with an identifier.
get() - returns the complete object from database.
for more details click this link
默认情况下,hibernate 创建运行时代理。除非指定提取模式或将其设置为 false,否则它将对象作为代理加载。
这是因为一旦对象被加载到缓存中,接下来的后续调用就会执行可重复读取。
- 虽然这个对象的状态从persistent变成了detached
可以通过两种方式检索实体。
load() - 返回带有标识符的代理对象。
get() - 从数据库返回完整的对象。
有关更多详细信息,请单击此链接
回答by Ashish Chaurasia
Actually, both functions are use to retrieve an object with different mechanism,
实际上,这两个函数都用于检索具有不同机制的对象,
session.load()
It will always return a “proxy” (Hibernate term) without hitting the database. In Hibernate, proxy is an object with the given identifier value, its properties are not initialized yet, it just look like a temporary fake object. If no row found , it will throws an ObjectNotFoundException.
session.get()
It always hit the database and return the real object, an object that represent the database row, not proxy. If no row found , it return null.
会话加载()
它将始终返回“代理”(休眠术语)而不会访问数据库。在 Hibernate 中,proxy 是一个具有给定标识符值的对象,它的属性尚未初始化,它看起来就像一个临时的假对象。如果没有找到行,它将抛出一个 ObjectNotFoundException。
会话.get()
它总是命中数据库并返回真实的对象,一个代表数据库行的对象,而不是代理。如果没有找到行,则返回 null。
回答by LMG
Here is a simple explanation of what you need: http://www.mkyong.com/hibernate/different-between-session-get-and-session-load/
以下是您需要的简单说明:http: //www.mkyong.com/hibernate/different-between-session-get-and-session-load/
Or by looking at the API: http://docs.jboss.org/hibernate/orm/4.3/javadocs/
或者通过查看 API:http: //docs.jboss.org/hibernate/orm/4.3/javadocs/
with get
: Return the persistent instance of the given named entity. The persistent one, so the one stored in the database.
with get
:返回给定命名实体的持久实例。持久的,所以存储在数据库中的那个。
with load
: Read the persistent state associated with the given identifier into the given transient instance.
with load
:将与给定标识符关联的持久状态读入给定的瞬态实例。
In the first link you find very useful examples to test the differences..
在第一个链接中,您会找到非常有用的示例来测试差异。
回答by user4575782
hibernatesession.get() will fetch the real object from the database and hibernatesession.load() will return proxy without hitting the database. For more details click here. It explains get and load method and their difference with example codes.
hibernatesession.get() 将从数据库中获取真实对象, hibernatesession.load() 将返回代理而不访问数据库。欲了解更多详情,请点击此处。它解释了 get 和 load 方法以及它们与示例代码的区别。
回答by Mohit Singh
When you call session.load() method, it will always return a “proxy” object, whats the meaning of proxy object ?
Proxy means, hibernate will prepare some fake object with given identifier value in the memory without hitting the database, for example if we call session.load(Student.class,new Integer(107)); > hibernate will create one fake Student object [row] in the memory with id 107, but remaining properties of Student class will not even be initialized.
当你调用 session.load() 方法时,它总是会返回一个“代理”对象,代理对象是什么意思?代理意味着,hibernate 将在内存中准备一些具有给定标识符值的假对象,而不会访问数据库,例如,如果我们调用 session.load(Student.class,new Integer(107)); > hibernate 会在内存中创建一个 id 为 107 的伪 Student 对象 [row],但是 Student 类的剩余属性甚至不会被初始化。
GET
得到
When you call session.get() method, it will hit the database immediately and returns the original object. If the row is not available in the database, it returns null.
当你调用 session.get() 方法时,它会立即命中数据库并返回原始对象。如果该行在数据库中不可用,则返回 null。
回答by Chandra Shekhar Goka
** Load:** Whenever the load()method is called, the hibernate creates a proxy object of a POJO class, and it will set the id to the proxy object, then it returns the proxy object to the program. Based on the operations performed on the proxy object, the hibernate will decide whether to go cache or database to load the data. This process is called lazy loading.
** Load:** 每当load()方法被调用时,hibernate 会创建一个 POJO 类的代理对象,并将 id 设置为代理对象,然后将代理对象返回给程序。根据对代理对象执行的操作,hibernate 将决定是去缓存还是数据库来加载数据。这个过程称为延迟加载。
** Get:** When we call the get()method, then hibernate first goes to first level cache and if that object doesn't exist in the first level cache then it goes to the database and loads the object from the database. If Id doesn't exist in the database, then get() method returns null. When get() method is called no proxy object is created, hence it is called as early loading.
** Get:** 当我们调用get()方法时,hibernate 首先进入一级缓存,如果一级缓存中不存在该对象,则它进入数据库并从数据库加载对象。如果数据库中不存在 Id,则 get() 方法返回 null。当 get() 方法被调用时,不会创建代理对象,因此它被称为提前加载。
Ref : http://docs.jboss.org/hibernate/orm/4.3/javadocs/
参考:http: //docs.jboss.org/hibernate/orm/4.3/javadocs/
Complete Example you can find @ my blog: http://www.onlinetutorialspoint.com/hibernate/hibernate-session-differences-between-load-and-get.html
完整的例子你可以找到@我的博客:http: //www.onlinetutorialspoint.com/hibernate/hibernate-session-differences-between-load-and-get.html
回答by Ravindra Singh
Load: when we call session.load() method it doesn't hit directly database. It creates and return proxy object if object didn't belongs in db it throws "ObjectNotFountException". And supports lazy loading.
加载:当我们调用 session.load() 方法时,它不会直接命中数据库。如果对象不属于数据库,它会创建并返回代理对象,它会抛出“ObjectNotFountException”。并且支持延迟加载。
Get: It hits directly object in db and gives original value if object not found then it returns null. And it supports eager loading.
Get:它直接命中db中的对象,如果找不到对象则返回原始值,然后返回null。并且它支持预先加载。
回答by dk24
From the above example - both the functions are not working same.
从上面的例子来看 - 这两个功能的工作方式不同。
load() - hibernate will only load proxy of the object with the specified ID. All the properties will not be set in advanced. Once you call the getter methods on the object, the query will be issues. So when you can a getAccount method , select query will be issued and the result object will be saved in cache as it is retrieved by ID. So any subsequent calls via get will not result any select statement.
load() - 休眠将只加载具有指定 ID 的对象的代理。不会预先设置所有属性。一旦在对象上调用 getter 方法,查询就会出现问题。因此,当您可以使用 getAccount 方法时,将发出选择查询,并且结果对象将在通过 ID 检索时保存在缓存中。因此,通过 get 进行的任何后续调用都不会产生任何选择语句。
get() - will always retrieve the object from database with full properties populated. For properties defined in collections, depends on lazy initialization configuration. Please note - Any subsequent calls on the same session will return the object from the cache only and hence no queries will be returned. That is what happening with the call to get method in the first time and the second time as the object is ready in cache by calling the acc.getBalance() on the object retrieved by load.
get() - 将始终从填充了完整属性的数据库中检索对象。对于集合中定义的属性,取决于延迟初始化配置。请注意 - 对同一会话的任何后续调用都将仅从缓存中返回对象,因此不会返回任何查询。这就是在第一次和第二次调用 get 方法时发生的情况,因为通过在加载检索的对象上调用 acc.getBalance(),对象在缓存中准备就绪。
回答by David Pham
Don't forget performance aspect between get and load method
不要忘记 get 和 load 方法之间的性能方面
The get() method fetches data as soon as it's executed while the load() method returns a proxy object and fetches only data when object properties is required. So that the load() method gets better performance because it support lazy loading. Whe should use the load() method only when we know data exists because it throws exception when data is not found.
get() 方法在执行后立即获取数据,而 load() 方法返回代理对象,并且仅在需要对象属性时获取数据。使 load() 方法获得更好的性能,因为它支持延迟加载。只有当我们知道数据存在时才应该使用 load() 方法,因为它在找不到数据时抛出异常。
You can see the example that demo this difference on the tutorial Difference between get and load method in Hibernate
您可以在Hibernate中的get和load方法之间的差异教程中看到演示这种差异的示例
回答by Jagadeesh
Use load:
使用负载:
If you are sure about the object availability that you are retrieving from DB. Else you will end up catching ObjectNotFoundException.
When you have heavy object to be loaded (Since it loads lazily whenever you use it)
如果您确定要从 DB 检索的对象可用性。否则,您将最终捕获 ObjectNotFoundException。
当你有重物要装载时(因为你每次使用它都会懒惰地装载)
Use get:
使用获取:
- If you are not sure about the object availability in the DB.
- You get luxury to check for null, when there is not object available in DB.
- When you have light object to be loaded (since it loads eagerly).
- 如果您不确定数据库中的对象可用性。
- 当 DB 中没有可用的对象时,您可以奢侈地检查 null。
- 当您要加载轻型对象时(因为它急切加载)。