【问题标题】:Quering JPA TABLE_PER_CLASS mapping on One to One relationship查询一对一关系上的 JPA TABLE_PER_CLASS 映射
【发布时间】:2010-06-29 19:48:21
【问题描述】:

我正在尝试使用继承策略 TABLE_PER_CLASS 映射 JPA(使用 Hibernate)一对一关系。这是一个例子:

@Entity
public class DrivingLicense {

    @OneToOne(targetEntity = Human.class, cascade = CascadeType.ALL, fetch=FetchType.LAZY)
    @JoinColumn
    private Human human;

    @SuppressWarnings("unchecked")
    public static List<DrivingLicense> findMansDrivingLicenses(Long id) {
        if (id == null) return null;
        return entityManager()
            .createQuery("select o from DrivingLicense o left join fetch o.human where o.id = :id")
            .setParameter("id", id)
            .getResultList();
    }

}

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Human {
   ...
}

@Entity
public class Man extends Human {
   ...
}

@Entity
public class Mutant extends Human {
   ...
}

当我调用“findMansDrivingLicenses”来检索所有男性的驾驶执照时,休眠会使用两个表(MAN 和 MUTANT)执行“UNION ALL”。按照日志输出:

select
        drivinglic0_.id as id3_0_,
        human1_.id as id0_1_,
        drivinglic0_.first_name as first2_3_0_,
        drivinglic0_.human as human3_0_,
        drivinglic0_.last_name as last3_3_0_,
        drivinglic0_.type as type3_0_,
        drivinglic0_.version as version3_0_,
        human1_.version as version0_1_,
        human1_.comment as comment1_1_,
        human1_.behavior as behavior2_1_,
        human1_.clazz_ as clazz_1_ 
    from
        driving_license drivinglic0_ 
    left outer join
        (
            select
                id,
                version,
                comment,
                null as behavior,
                1 as clazz_ 
            from
                man 
            union
            all select
                id,
                version,
                null as comment,
                behavior,
                2 as clazz_ 
            from
                mutant 
        ) human1_ 
            on drivinglic0_.human=human1_.id 
    where
        drivinglic0_.id=?

有什么方法可以防止休眠执行“UNION ALL”并且只加入 MAN 表?

【问题讨论】:

    标签: hibernate jpa


    【解决方案1】:

    尝试使用类

    select o from DrivingLicense o left join fetch o.human human where o.id = :id and human.class = Man
    

    更新

    检索您与本机查询的关系

    session = sessionFactory.openSession();
    
    StringBuilder query = new StringBuilder();
    query
    .append("select ")
        .append("{driving.*}, {man.*} ")
    .append("from ")
        .append("DrivingLicense driving ")
    .append("left join ")
        .append("Man man ")
    .append("on ")
        .append("driving.human_id = man.id ")
    .append("where ")
        .append("driving.id = :id");
    
    Query _query = session.createSQLQuery(query.toString())
                          /**
                            * It means: driving alias WILL BE MAPPED TO DrivingLicense Entity
                            */
                          .addEntity("driving", DrivingLicense.class)
                          /**
                            * It means: man alias WILL BE MAPPED TO human property of DrivingLicense Entity
                            */
                          .addJoin("man", "driving.human")
                          .setParameter("id", <DRIVING_LICENSE_ID_GOES_HERE>);
    
    
    Object [] resultArray = query.list.get(0);
    
    session.close();
    

    DrivingLicense driving = resultArray[0];
    /**
      * YES, Man IS NOT automatically MAPPED TO driving.human property
      * You have to set up manually
      */
    Man man = resultArray[1];
    
    driving.setHuman(man);
    

    【讨论】:

    • 查询已修改,仍然与表 man 和突变体连接(联合):( 添加了 @org.hibernate.annotations.Entity(polymorphism = PolymorphismType.EXPLICIT) 什么也没有!
    • @monit06 我很确定它的发生是因为您有 TABLE_PER_CLASS 策略。因为必须保证身份,Hibernate 确保所有子类不会返回相同的身份。如果你真的想避免这种行为,你应该使用 MappedSuperclass 而不是继承。
    • @monit06 或者使用 SINGLE_TABLE 策略。 JOINED 策略也有同样的问题。
    • 已尝试,但使用 MappedSuperclass 我无法使用 DrivingLicense 创建抽象关系。有没有办法进行本地查询来检索两个实体,DrivingLicence 和 Man,加入?
    • @monit06 我明白了。这说得通。我将向您展示如何使用原生查询来实现您的目标
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    相关资源
    最近更新 更多