我注意到我的一个应用程序中有一些奇怪的行为。我在两个类 Frame 和 Brand 之间有一个 ManyToOne 关系。就数据库而言,关系是单向的。表中的每个 Frame 都有一个 brand_id 列,但 Brand 没有任何指向另一个方向的列。到目前为止一切都很好,但在实际代码中,我有时需要获取有关与特定品牌关联的所有框架的信息。为了促进这一点,我在 Brand 类中添加了一个字段,该字段包含一组框架 ID,并使用 @ElementCollection 和 @CollectionTable 对其进行注释。
这是事情变得有点时髦的地方。Frame 类是使用单表继承的层次结构的一部分。并非所有映射到该表的类都有品牌,因此brand_id 列必须可以为空。从我目前能够确定的情况来看,对于使用@ElementCollection 注释的关系,Hibernate 强制“可为空”为假。似乎没有任何文档解释原因。相关代码可以在 hibernate-core-5.3.13.Final.jar 的 'org.hibernate.cfg.Ejb3JoinColumn.buildJoinTableJoinColumns()' 中找到,但它所说的只是
currentJoinColumn.setNullable(false); //我打破了规范,但它是好的
有什么方法可以覆盖 Hibernate 中的这个限制吗?如果没有,是否有其他方法可以在不使用@ElementCollection 的情况下做我想做的事情?
我的代码:
@Entity(name = "Frame")
@DiscriminatorValue("FRAME")
public class Frame extends Product
{
@ManyToOne(optional=true)
@JoinColumn(name = "brand_id")
@IndexedEmbedded
protected Brand brand;
public Brand getBrand()
{
return brand;
}
}
@Entity(name = "Brand")
@Table(name = "brands")
public class Brand extends Entity
{
@ElementCollection
@CollectionTable(name = "products", joinColumns = @JoinColumn(name = "brand_id"))
@Column(name = "id")
protected Set<BigInteger> frameIds;
public Set<BigInteger> getFrameIds()
{
return frameIds;
}
public void setFrameIds(Set<BigInteger> frameIds)
{
this.frameIds = frameIds;
}
}
public class Foo extends Entity
{
@ManyToOne
@JoinColumn(name = "brand_id")
protected Brand brand;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "frames_to_features", inverseJoinColumns = {
@JoinColumn(name = "frame_id", referencedColumnName = "id") }, joinColumns = {
@JoinColumn(name = "feature_id", referencedColumnName = "id") })
protected Set<Frame> frames;
public List<BigInteger> getExcludedFrameIds()
{
List<BigInteger> brandFrames = new ArrayList<BigInteger>();
if (getBrand() != null)
{
brandFrames.addAll(getBrand().getFrameIds());
Set<BigInteger> localFrames = getFrameIds();
if (localFrames != null)
{
brandFrames.removeAll(localFrames);
}
}
return brandFrames;
}
}