如果您将 Hibernate 3.6 与 JPA 2.0 一起使用,则有一个解决方法。这不是更好的解决方案,但它对我来说非常完美。
我已经用@Where hibernate 注释复制了实体。这意味着每次你使用这个实体的连接时,hibernate 都会在生成的 SQL 的连接语句上添加额外的条件。
例如,最初我们有以下示例:
@Entity
@Table(name = "PERSON")
public class Person {
@Id
@Column(name = "PERSON_ID")
private Long id;
@Id
@Column(name = "PERSON_NAME")
private String name;
@OneToMany(mappedBy = "person", fetch = FetchType.LAZY)
private Set<Address> addresses;
}
@Entity
@Table(name = "ADDRESS")
public class Address {
@Id
@Column(name = "ADDRESS_ID")
private Long id;
@Id
@Column(name = "ADDRESS_STREET")
private String street;
@ManyToOne
@JoinColumn(name = "PERSON_ID")
private Person person;
}
为了在条件加入上添加额外的条件,我们需要复制地址 @Entity 映射,添加 @Where 注释 @Where(clause = "ADDRESS_TYPE_ID = 2")。
@Entity
@Table(name = "ADDRESS")
@Where(clause = " ADDRESS_TYPE_ID = 2")
public class ShippingAddress {
@Id
@Column(name = "ADDRESS_ID")
private Long id;
@Id
@Column(name = "ADDRESS_STREET")
private String street;
@OneToOne
@JoinColumn(name = "PERSON_ID")
private Person person;
}
此外,我们需要为新实体添加重复映射关联。
@Entity
@Table(name = "PERSON")
public class Person {
@Id
@Column(name = "PERSON_ID")
private Long id;
@Id
@Column(name = "PERSON_NAME")
private String name;
@OneToMany(mappedBy = "person", fetch = FetchType.LAZY)
private Set<Address> addresses;
@OneToOne(mappedBy = "person")
private ShippingAddress shippingAddress;
}
最后,您可以在您的条件中使用与此特定实体的联接:
PersonRoot.join(Person_.shippingAddress, JoinType.LEFT);
Hibernate Snippet SQL 应该是这样的:
left outer join
address shippingadd13_
on person11_.person_id=shippingadd13_.person_id
and (
shippingadd13_.ADDRESS_TYPE_ID = 2
)