2010-06-29 52 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