我有一个带有两个子类的抽象父类,我希望子类拥有自己的表。我还有另一个与父类有关系的类:
// Class that has the mapping to the abstract class
@Entity
@Table(name="telephone_numbers")
public class TelephoneNumber implements Serializable {
@Id
@Column(name="number")
private String number;
@Column(name="originating_carrier")
private String originatingCarrier;
@OneToOne(mappedBy = "number")
private TelephoneNumberAssignment assignment;
... getters and setters ...
}
// Classes involved in inheritance
public abstract class TelephoneNumberAssignment implements Serializable {
@Id
@OneToOne
@JoinColumn(name="number")
private TelephoneNumber number;
... getters and setters ...
}
@Entity
@Table(name="telephone_numbers_fixed_line")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class FixedLineNumberAssignment extends TelephoneNumberAssignment {
@Column(name="recorded")
private Boolean recorded;
public FixedLineNumberAssignment() {
}
... getters and setters ...
}
@Entity
@Table(name="telephone_numbers_mobile")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class MobileNumberAssignment extends TelephoneNumberAssignment {
@ManyToOne
@JoinColumn(name = "customer_id")
private Customer customer;
public MobileNumberAssignment() {
}
... getters and setters ...
}
根据this question的答案,为了让我的超类中的JPA注释转移到子类,我需要使用@MappedSuperclass
。但是,由于需要映射到超类,会发生以下异常:
Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: com.vtsl.domain.numbering.TelephoneNumber.assignment, referenced property unknown: com.vtsl.domain.numbering.TelephoneNumberAssignment.number
根据this question的答案,我可以使用TABLE_PER_CLASS
来解决此问题。但是,如果我这样做,我的超类JPA注释似乎不会延续;如果我执行JPQL查询
return entityManager.createQuery("SELECT mob FROM MobileNumberAssignment as mob INNER JOIN FETCH mob.number", MobileNumberAssignment.class).getResultList();
返回的结果没有填充number
字段(进一步检查时,我发现hibernate在尝试解析结果对象的属性时没有检测到number
属性)。但是,当我执行以下操作时:
//Result set has 1 object
entityManager
.createQuery("SELECT mob FROM MobileNumberAssignment as mob INNER JOIN FETCH mob.number WHERE mob.number.number = :number", MobileNumberAssignment.class)
.setParameter("number", "number that exists")
.getResultList()
//Result set has 0 object
entityManager
.createQuery("SELECT mob FROM MobileNumberAssignment as mob INNER JOIN FETCH mob.number WHERE mob.number.number = :number", MobileNumberAssignment.class)
.setParameter("number", "number that does not exist")
.getResultList()
结果似乎表明该参数毕竟成功解决了。
为什么number
属性不会被填充?
答案 0 :(得分:0)
看来我从症状中得出了所有错误的结论。问题根本不在于继承规范,而在于映射主键的规范。根据我发现的每一种资源
@Id
@OneToOne
@JoinColumn(name="number")
private TelephoneNumber number;
应该工作得很好,但似乎在我使用的hibernate版本(4.10)它没有。更改映射以使用@MapsId
解决了我正在观察的问题,使新的(现在正在工作的)TelephoneNumberAssignment
看起来像:
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class TelephoneNumberAssignment implements Serializable {
@Id String numberString;
@MapsId
@OneToOne
@JoinColumn(name="number")
private TelephoneNumber number;
... getters and setters ...
}