2010-06-29 54 views
1

我试图用继承策略TABLE_PER_CLASS映射JPA(使用Hibernate)一对一关系。下面是一个例子:当我打电话“findMansDrivingLicenses”检索所有男人的驾驶执照冬眠做一个“UNION ALL”有两个表(MAN和突变)在一对一关系上查询JPA TABLE_PER_CLASS映射

@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 { 
    ... 
} 

。按照日志输出:

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表加入?

回答

0

尝试使用类

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

UPDATE

检索与原住民的关系查询

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); 
+0

查询修改,仍然加入(联合所有)与表男人和突变::( 增加@ org.hibernate.annotations.Entity(多态性= PolymorphismType.EXPLICIT),没有任何东西! – monit06 2010-06-30 19:36:45

+0

@ monit06我很确定它发生是因为你有一个** TABLE_PER_CLASS **策略。因为**身份必须保证**,所以Hibernate确保所有的子类不会返回相同的身份。如果你真的想避免这种行为,你应该使用MappedSuperclass而不是继承。 – 2010-06-30 20:43:09

+0

@ monit06或使用** SINGLE_TABLE **策略。加入战略也有同样的问题。 – 2010-06-30 20:48:24