Hol*_*olm 7 java mysql hibernate cascade
这就是我想要做的.
班级家长
@OneToOne(mappedBy = "parent", cascade = CascadeType.ALL)
public Child getChild()
Run Code Online (Sandbox Code Playgroud)
班级孩子
@OneToOne(fetch = FetchType.LAZY)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name="parent_id")
public Parent getParent()
Run Code Online (Sandbox Code Playgroud)
我有点1,3,4完全工作,第5点部分工作,仍然需要解决如何翻译更新部分indo DDL.
第2点是这里的一个大问题,我目前的解决方案是父母不会懒惰加载孩子.然而,孩子懒得加载父母,但是反转注释会使级联变得混乱(第3,4和5点).
我现在很困惑,希望我错过了一些明显的东西,所以任何帮助都会非常感激.
编辑: Adeel Ansari要求的代码
'fetch = FetchType.LAZY'已添加到类Parent,否则与上面相同.
IParentDAO parentDAO = DAOFactory.getFactory().getParentDAO();
parentDAO.beginTransaction();
//findByPrimaryKey uses 'org.hibernate.Session.get(Class clazz, Serializable id)'
parentDAO.findByPrimaryKey(1l);
parentDAO.commitTransaction();
Run Code Online (Sandbox Code Playgroud)
生成的hibernate查询,一个获取Parent,一个获取Child:
Hibernate: select parent0_.id as id0_0_ from parents parent0_ where parent0_.id=?
Hibernate: select child0_.id as id1_0_, child0_.parent_id as parent2_1_0_ from childs child0_ where child0_.parent_id=?
Run Code Online (Sandbox Code Playgroud)
这是findByPrimaryKey的代码:
public class HibernateParentDAO extends HibernateDAO<Parent, Long> implements IParentDAO {
public HibernateParentDAO() {
super(Parent.class);
}
}
public abstract class HibernateDAO<T, ID extends Serializable> implements IGenericDAO<T, ID> {
private Class<T> persistentClass;
public HibernateDAO(Class<T> c) {
persistentClass = c;
}
@SuppressWarnings("unchecked")
public T findByPrimaryKey(ID id) {
return (T) HibernateUtil.getSession().get(persistentClass, id);
}
}
Run Code Online (Sandbox Code Playgroud)
ili*_*den 20
我一直有类似的问题.有几种不同的解决方案,但所有这些都是解决方法.
简短的回答是:Hibernate不支持懒惰的一对一关系.
答案很长(解决方法)是:
声明关系在一边(孩子)是一对一,在另一边(父母)是一对多.因此,parent.getchild()返回一个集合,但它将能够使用延迟加载.
您可以尝试让父级和子级共享主键,但这需要您更改架构.
您可以尝试在数据库中配置反映此一对一关系的视图.
Ade*_*ari 11
[此部分不再存在]
在Parent下面修改它,
@OneToOne(mappedBy = "parent", cascade = CascadeType.ALL, fetch=FetchType.LAZY)
public Child getChild()
Run Code Online (Sandbox Code Playgroud)
应该管用.
[编辑解释为什么它不起作用]
在加载B之后,你可以调用getCee()来获得C.但是看看,getCee()是你的类的一个方法,而Hibernate无法控制它.Hibernate不知道有人打算调用getCee().这意味着Hibernate必须在从数据库加载B时将适当的值放入"cee"属性.
如果为C启用了代理,Hibernate可以放置一个尚未加载的C代理对象,但是当有人使用它时将加载它.这为一对一提供了延迟加载.
但现在想象你的B对象可能有也可能没有关联的C(约束="假").当特定B没有C时,getCee()应该返回什么?空值.但请记住,Hibernate必须在设置B时设置正确的"cee"值(因为它不知道有人何时会调用getCee()).代理在这里没有帮助,因为代理本身已经是非null对象.
如果你的B-> C映射是强制性的(约束=真),Hibernate将使用C代理导致延迟初始化.但是如果你允许B没有C,那么Hibernate只是在它加载B时检查C的存在.但是检查存在的SELECT效率很低,因为相同的SELECT可能不仅仅检查存在,而是加载整个对象.懒惰的装载消失了.
参考:http://community.jboss.org/wiki/Someexplanationsonlazyloadingone-to-one
[编辑包含一个变通方法]
您可以使用optional=false和@LazyToOne不是可选的关系.别忘了包括cascade={CascadeType.PERSIST,CascadeType.REMOVE}.因为,非选择性关系显而易见.以下是一个例子,
@OneToOne(mappedBy="parent", optional=false, fetch=FetchType.LAZY, cascade={CascadeType.PERSIST,CascadeType.REMOVE})
@LazyToOne(LazyToOneOption.PROXY)
public Child getChild(){...}
Run Code Online (Sandbox Code Playgroud)
这应该对你有用,因为我可以看到你正在使用cascade=CascadeType.ALL,这意味着不可选.不是吗?但是对于可选关系,您可能会考虑iliaden给出的解决方法.