开发者

Quering JPA TABLE_PER_CLASS mapping on One to One relationship

开发者 https://www.devze.com 2023-01-05 16:23 出处:网络
I am trying to map a JPA (using Hibernate) one-to-one relationship with a inheritance strategy TABLE_PER_CLASS. Here is an example:

I am trying to map a JPA (using Hibernate) one-to-one relationship with a inheritance strategy TABLE_PER_CLASS. Here is an example:

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

When I call "findMansDrivingLicenses" to retrieve all man's driving licenses hibernate does a "UNION ALL" with both tables (MAN and MUTANT). Follow the log output:

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
                ma开发者_StackOverflow社区n 
            union
            all select
                id,
                version,
                null as comment,
                behavior,
                2 as clazz_ 
            from
                mutant 
        ) human1_ 
            on drivinglic0_.human=human1_.id 
    where
        drivinglic0_.id=?

Is there any way to prevent hibernate to do this "UNION ALL" and only join with MAN table?


Try to use class

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

UPDATE

retrieve your relationship with Native queries

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

And

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

精彩评论

暂无评论...
验证码 换一张
取 消