| Using have a joined hierachy with:
- Base class BaseEntity
- Two sub classes ChildEntity1 and ChildEntity2.
- Both sub classes have a column with the same name (e.g. NAME) which is not in the BaseEntity.
- Another entity OtherEntity which has a ChildEntity1 property
When doing a JQL join from OtherEntity to ChildEntity1 hibernate appears to disregard which entity the NAME column is on, and picks the one on ChildEntity2 rather than the ChildEntity1 which is specified in the query (see below). e.g. Base Class:
@Entity
@Table(name = "BASE_ENTITY")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "TYPE")
public class BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
public Long getId() {
return id;
}
}
Child Entity 1:
@Entity
@Table(name = "CHILD_ENTITY1")
@PrimaryKeyJoinColumn(name = "BASE_ID")
@DiscriminatorValue("CE1")
public class ChildEntity1 extends BaseEntity {
@Column(name = "NAME", nullable = false)
private String name;
public String getName() {
return name;
}
}
Child Entity 2:
@Entity
@Table(name = "CHILD_ENTITY2")
@PrimaryKeyJoinColumn(name = "BASE_ID")
@DiscriminatorValue("CE1")
public class ChildEntity2 extends BaseEntity {
@Column(name = "NAME", nullable = false)
private String name;
public ChildEntity2(String name) {
this.name = name;
}
}
Other Entity:
@Entity
@Table(name = "OTHER_ENTITY")
public class OtherEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(targetEntity = BaseEntity.class)
@JoinColumn(name = "CE1_ID", nullable = false)
private ChildEntity1 child;
public Long getId() {
return id;
}
public ChildEntity1 getChild() {
return child;
}
}
Repository:
public interface OtherEntityRepository extends CrudRepository<OtherEntity, Long> {
@Query("SELECT o FROM OtherEntity o LEFT JOIN o.child c WHERE c.name = ?1")
List<OtherEntity> getAllByChildName(String name);
}
Turning on Hibernate query logging logging.level.org.hibernate.SQL=DEBUG shows the query becomes:
select
otherentit0_.id as id1_3_,
otherentit0_.ce1_id as ce2_3_
from other_entity otherentit0_
left outer join base_entity baseentity1_
on otherentit0_.ce1_id=baseentity1_.id
left outer join child_entity2 baseentity1_1_
on baseentity1_.id=baseentity1_1_.base_id
left outer join child_entity1 baseentity1_2_
on baseentity1_.id=baseentity1_2_.base_id
where baseentity1_1_.name=?
This is incorrect. The where clause should be on baseentity1_2_.name This seems to be a result of using the @ManyToOne(targetEntity = BaseEntity.class) which for this simple example is not required, but for many more advanced hierachies will be. |