rap*_*apt 10 orm hibernate java-ee
我试图了解Hibernate 3.6 session.get()
和Hibernate 3.6的返回对象和行为的区别session.load()
.
来自javadoc:
得到():
返回给定实体类的持久实例和给定标识符,如果没有这样的持久实例,则返回null.(如果实例已与会话关联,则返回该实例.此方法永远不会返回未初始化的实例.)
加载():
假定实例存在,返回给定实体类的持久实例和给定标识符.当访问非标识符方法时,此方法可能会返回按需初始化的代理实例.
我有三个问题:
javadoc没有说什么时候load()
可能会返回一个代理 - 有没有办法提前知道它?
当load()
返回代理-这意味着load()
没有访问数据库,对吗?那么如果我提供load()
了数据库中不存在的标识符呢?我现在将在会话中拥有一个具有无效ID的代理(没有获得异常).现在我想让另一个持久化实例指向该代理 - 它会起作用吗?对于这种情况,我不需要初始化代理,我只需要它的id(即使它是无效的,因为它不在数据库中).所以我想我问的是我的描述是否正确,并且我总是需要load()
在返回的对象之后签出,isInitialized()
以确保它代表一个有效的实体(或至少是一个有效的代理),即具有有效的ID.
此外,如果load()
返回代理会发生什么- 所以代理是已经与会话关联的实例.然后根据以下描述get()
:"如果实例已经与会话关联,则返回该实例." - 那么get()
返回代理吗?因为根据以下描述get()
:"此方法永远不会返回未初始化的实例."
谢谢!
UPDATE
以下是否正确?
(A)我认为两者load()
并get()
会首先尝试才去DB检查会话缓存-所以它不会是正确的说,任何人总是打DB或总是返回的代理.
(B)初始化代理与原始实例不同,您可以在此处阅读:http://blog.xebia.com/2008/03/08/advanced-hibernate-proxy-pitfalls/
Ken*_*han 19
(1),(3):
是.你是对的.load()
并且get()
将首先检查会话中是否存在具有相同PK的实例.
如果是,则从会话中返回该实例.(它可能是代理或实际的实体类实例)
如果不是,load()
将创建并返回代理,同时get()
将命中DB并返回实际实体类的实例.
两个方法中返回的对象将在之后的会话中关联并保留.
因此,无论是get()
或load()
返回代理或实际的实体类取决于您是否使用get()或load(),以获得在首次当前会话同一PK的实例.
您可以通过执行以下测试来证明此行为:
Session session = HibernateUtil.getSessionFactory().openSession();
Item loadItem= (Item ) session.load(Item.class, 1);
System.out.println(loadItem.getClass().getName());
Item getItem = (Item ) session.get(Item .class, 1);
System.out.println(getItem .getClass().getName());
Run Code Online (Sandbox Code Playgroud)
如果它是代理,则打印的类名称将与实际的实体类名称不同.只需更改to的执行顺序load()
并get()
查看效果即可.
(2):
如果load()返回一个代理,它将不会在访问期间load()
访问数据库.如果访问了除PK之外的映射属性,并且没有与该会话关联的具有相同PK值的实例,则代理将仅访问该数据库.
代理访问数据库后,具有相同代理PK的实例将与该会话关联.因此,当您再次从代理获取另一个属性或者您使用get()
获取相同PK的实例时,数据库将不会访问,因为可以从会话中找到值.
例如:
/**Session starts***/
Item item = (Item) session.load(Item.class, new Long(1));
item.getId(); //Will not access DB as only the identifier property is access
item.getDescription(); // access the DB and initialize the proxy . After that , the item proxy is said to be initialized
item.getPrice(); //will not access DB as the item with the PK 1 can be get from the session
Item item2 = session.get(Item.class, new Long(1)) //will not access DB as the item with the PK 1 can be get from the session
Run Code Online (Sandbox Code Playgroud)
如果您load()
的实例具有无效ID,然后访问该属性或isInitialized()
在此代理上调用方法(如),ObjectNotFoundException
则将抛出.因此,如果您可以捕获ObjectNotFoundException
,则意味着代理加载了无效ID.
如果要确保ID在运行时有效,则应使用get()
并检查返回的实例是否为空.load()
在设置外键约束时很有用.看到这个
归档时间: |
|
查看次数: |
12368 次 |
最近记录: |