2010-06-29 5 views
1

J'essaye de mapper une relation un-à-un JPA (en utilisant Hibernate) avec une stratégie d'héritage TABLE_PER_CLASS. Voici un exemple:Quering Mappage JPA TABLE_PER_CLASS sur une relation un à un

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

Quand j'appelle "findMansDrivingLicenses" pour récupérer les permis de conduire de tout homme hibernent fait une "UNION ALL" avec les deux tables (MAN et MUTANT). Suivez la sortie du journal:

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=? 

Est-il possible d'empêcher veille prolongée de le faire « UNION ALL » et ne se joindre à la table MAN?

Répondre

0

Essayez d'utiliser la classe

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

MISE À JOUR

récupérer votre relation avec les Requêtes natives

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(); 

Et

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

Requête modifiée, toujours en train de rejoindre (union tout) avec tables man et mutant :( Ajouté @ org.hibernate.annotations.Entity (polymorphism = PolymorphismType.EXPLICIT) et rien de trop! – monit06

+0

@ monit06 Je suis sûr qu'il se produit parce que vous avez une stratégie ** TABLE_PER_CLASS **. Parce que ** l'identité doit être garantie **, Hibernate s'assure que toutes les sous-classes ne renvoient pas la même identité. Si vous voulez vraiment éviter ce genre de comportement, vous devriez utiliser MappedSuperclass au lieu de l'héritage. –

+0

@ monit06 Ou utilisez la stratégie ** SINGLE_TABLE **. La stratégie JOINTE a aussi le même problème. –