休眠OneToOne延迟加载和级联 [英] Hibernate OneToOne lazy loading and cascading

查看:125
本文介绍了休眠OneToOne延迟加载和级联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  1. 创建一个与子对象具有OneToOne关系的父对象

  2. 父母必须使用延迟加载获取孩子

  3. 如果父母被移除,孩子也是如此
  4. 如果孩子是已删除,不应影响父级
  5. 级联更新和删除必须转换为DDL



  6. class Parent

      @OneToOne(mappedBy =parent,cascade = CascadeType.ALL )
    public Child getChild()

    class Child
    $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ @ $ $ $ $ $ $ @ @ $ $ $ $ $ $ @ @ $ @ $ @ $ @ @ $ @ $ @ $ @ $ @ $ @ $ @ $ @ $ @ $ @ $ @ $ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ (name =parent_id)
    public Parent getParent()

    完全正常工作并且点5 部分工作,仍然需要解决如何转换DDL更新部分。 / p>

    第2点是这里最大的问题,我目前的解决方案是父母不会延迟加载孩子。然而,孩子懒惰地加载父母,但反转注释会混乱层叠(点3,4和5 )。



    I '现在非常困惑,希望我错过了一些明显的东西,所以任何帮助将不胜感激。



    编辑:要求的代码Adeel Ansari


    $ b 'fetch = FetchType.LAZY'已被添加到Parent类中,否则与上面相同。

      IParentDAO parentDAO = DAOFactory.getFactory()。getParentDAO(); 

    parentDAO.beginTransaction();
    // findByPrimaryKey使用'org.hibernate.Session.get(Class clazz,Serializable id)'
    parentDAO.findByPrimaryKey(1l);
    parentDAO.commitTransaction();

    由此产生的hibernate查询,一个读取Parent和一个读取Child:

      Hibernate:选择parent0_.id作为父母parent0_的id0_0_,其中parent0_.id =? 
    Hibernate:选择child0_.id作为id1_0_,child0_.parent_id作为来自childs child0_的parent2_1_0_,其中child0_.parent_id =?

    以下是findByPrimaryKey的代码:

      public class HibernateParentDAO extends HibernateDAO< Parent,Long>实现IParentDAO {

    public HibernateParentDAO(){
    super(Parent.class);
    }
    }

    public abstract class HibernateDAO< T,ID extends Serializable>实现IGenericDAO< T,ID> {
    私人课程< T>对PersistentClass;

    public HibernateDAO(Class< T> c){
    persistentClass = c;

    $ b @SuppressWarnings(unchecked)
    public T findByPrimaryKey(ID id){
    return(T)HibernateUtil.getSession()。get(persistentClass, ID);
    }
    }


    解决方案

    I有一个类似的问题。有几种不同的解决方案,但都是解决方法。



    简短的回答是:Hibernate不支持懒惰的一对一关系。



    长答案(解决方法)是:


    1. 声明关系为一一方(孩子)一对一,另一方(父母)一对多。因此, parent.getchild()会返回一个集合,但它可以使用延迟加载。

    2. 您可以尝试让父母和子女分享主键,但这需要您更改模式。 您可以尝试在数据库中配置一个反映这种一对一关系的视图。


    Here's what I'm trying to do.

    1. Create a parent with a OneToOne relation to a child
    2. The parent has to fetch the children using lazy loading
    3. If parent is removed, so is the child
    4. If the child is removed, the parent should not be affected
    5. The cascade update and delete has to be translated into DDL

    class Parent

    @OneToOne(mappedBy = "parent", cascade = CascadeType.ALL)
    public Child getChild()
    

    class Child

    @OneToOne(fetch = FetchType.LAZY)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @JoinColumn(name="parent_id")
    public Parent getParent()
    

    I've got point 1, 3, 4 fully working and Point 5 partially working, still need to solve how to translate the update part indo DDL.

    Point 2 is the big issue here, with my current solution the parent does not load the child lazily. The child however does load the parent lazily, but inverting the annotations would mess upp the cascading (points 3, 4 and 5).

    I'm very confused right now, hoping I've missed something obvious, so any help would be greatly appreciated.

    EDIT: Code requested by Adeel Ansari

    'fetch=FetchType.LAZY' has been added to class Parent, otherwise the same as above.

    IParentDAO parentDAO = DAOFactory.getFactory().getParentDAO();
    
    parentDAO.beginTransaction();
    //findByPrimaryKey uses 'org.hibernate.Session.get(Class clazz, Serializable id)'
    parentDAO.findByPrimaryKey(1l);
    parentDAO.commitTransaction();
    

    The resulting hibernate queries, one fetching Parent and one fetching 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=?
    

    Here's the code for 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);
        }
    }
    

    解决方案

    I've been having a similar issue. There are a few different solutions, but all of them are workarounds.

    The short answer is: Hibernate does NOT support lazy one-to-one relationships.

    The long answer (workaround) is:

    1. Declare the relationship to be one-to-one on one side (child), and one-to-many on the other side (parent). Thus a parent.getchild() returns a set, yet it will be able to use lazy loading.

    2. You can try to have the parent and the children to share the primary key, but this would require you to alter the schema.

    3. You can try to configure a view in your database reflecting this one-to-one relationship.

    这篇关于休眠OneToOne延迟加载和级联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆