我无法使用构建器.treat()方法获取JPA查询以将AbstractAddress
实体强制转换为其子类AddressStd
。
builder.equal( builder.treat(contracts.get("address"),
AddressStd.class
).get("houseNo"), std.getHouseNo());
背景
我使用JPA 2.1(使用Hibernate 5.0.2 FINAL)来映射遗留数据库,其中Customer
有0:n个联系人,每个Contact
都有AbstractAddress
子类型AddressStd
或AddressPOB
(邮政信箱)。联系人具有其他属性,但为了简单起见,它们未在下面显示。
域名模型
@Entity
@Table(name = "Customer")
public class Customer
@Id @Column(name = "ID", nullable = false)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_CUSTOMER_ID")
@SequenceGenerator(name="SEQ_CUSTOMER_ID", sequenceName="SEQ_CUSTOMER_ID")
private Long id;
@OneToMany(fetch = FetchType.LAZY, mappedBy="Customer", orphanRemoval=true, cascade=CascadeType.ALL)
private Set<Contact> contacts;
...
}
@Entity
@Table(name = "CONTACT")
public class Contact {
@Id @Column(name = "CONTACT_ID", nullable = false)
private Long id;
@Basic @Column(name = "ROLE", length = 30)
@Convert(converter = ProfileTypeConverter.class)
private ContactType type;
@OneToOne(fetch = FetchType.LAZY, mappedBy="contact", orphanRemoval=true, cascade=CascadeType.ALL)
private AbstractAddress address;
}
@Entity
@Table(name = "ADDRESS")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula( "case when PO_BOX_NUMBER is null then 'ADDRESS_STD' ELSE 'ADDRESS_POB' end" )
public abstract class AbstractAddress {
@Id @Column(name = "ID", nullable = false, precision = 0)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ADDRESS")
@SequenceGenerator(name = "SEQ_ADDRESS", sequenceName = "SEQ_ADDRESS")
private Long id;
@OneToOne
@PrimaryKeyJoinColumn(name = "CONTACT_ID", referencedColumnName = "ID")
private Contact contact;
@Basic @Column(name = "POSTAL_CODE", length = 10)
private String postcode;
@Basic @Column(name = "CITY", length = 40)
private String city;
@Basic @Column(name = "COUNTRY", length = 2)
@Convert(converter = CountryConverter.class)
private Country country;
@Basic(optional=false)
@Column(name = "LNG_CODE", length = 2)
@Convert(converter = LanguageConverter.class)
private Language language;
@Basic(optional=false)
@Column(name = "STATUS", length = 1)
@Convert(converter = BooleanActiveConverter.class)
private Boolean isActive = true;
}
@Entity
@DiscriminatorValue("ADDRESS_STD")
public class AddressStd extends AbstractAddress {
@Basic @Column(name = "HOUSE_NUMBER", length = 8)
private String houseNo;
@Basic @Column(name = "STREET_NAME", length = 30)
private String street;
...
}
@Entity
@DiscriminatorValue("ADDRESS_POB")
public class AddressPOB extends AbstractAddress {
@Basic
@Column(name = "PO_BOX_NUMBER", length = 8)
private String poBoxNo;
...
}
JPA查询
构建查询用于检索AbstractAddress
属性(city, postcode, country, language, isActive
),但我无法检索AddressStd
(houseNo, street
)和{{的子类属性1}}(AddressPOB
)分别作为
poBoxNo
抛出运行时异常
builder.equal(builder.treat(contracts.get("address"),
AddressStd.class
).get("houseNo"), std.getHouseNo());
我之前使用了构建器.treat()方法来转换类型,它工作正常。但在这种情况下.treat()无法将地址转换为java.lang.IllegalArgumentException: Unable to locate Attribute with the
given name [houseNo] on this ManagedType [com.compX.appY.domain.contacts.AbstractAddress]
?你们中的任何一个JPA大师都知道为什么,非常感谢,DaveT。
请参阅此处的CriteriaQuery构建器代码
AddressStd.class