我在JPA + Hibernate中有这些实体,Player
和AvatarAttributeOwnership
。前者有Set
后者,它定义了它拥有的化身属性。
@Entity
public class Player implements Serializable {
@Id
@GeneratedValue
private long id;
@OneToMany(fetch=FetchType.LAZY,mappedBy="owner",cascade=CascadeType.ALL)
private Set<AvatarAttributeOwnership> ownedAvatarAttributes;
...
}
@Entity
@Table(uniqueConstraints=@UniqueConstraint(columnNames={"owner","gender","type","attrId"}))
public class AvatarAttributeOwnership implements Serializable {
@Id
@GeneratedValue
@SuppressWarnings("unused")
private long id;
@ManyToOne
@JoinColumn(name="owner")
private Player owner;
// these three columns define the attribute (i.e. are attribute's key)
@Column
private String attrId;
@Column
private String gender;
@Column
private String type;
@Column
private Date ownedSince;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + attrId.hashCode();
result = prime * result + gender.hashCode();
result = prime * result + owner.hashCode();
result = prime * result + type.hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
AvatarAttributeOwnership other = (AvatarAttributeOwnership) obj;
if (!attrId.equals(other.attrId)) return false;
if (gender != other.gender) return false;
if (!owner.equals(other.owner)) return false;
if (!type.equals(other.type)) return false;
return true;
}
}
AvatarAttributeOwnerships的创建方式如下:
player = em.find(Player.class, playerId);
player.getAvatarAttributeOwnership().add(new AvatarAttributeOwnership(player, attrId, gender, type, new Date()));
em.persist(player);
我可以删除AvatarAttributeOwnership
中的所有者引用,同时保持在那里定义的唯一约束吗?
答案 0 :(得分:0)
您可以通过定义单向多对一关联来实现。这将生成一个连接表,其中包含所有者的id(在您的情况下是Player)的列和另一个具有子ID(AvatarAttributeOwnership)的列。有关说明,请参阅http://docs.jboss.org/hibernate/core/3.3/reference/en/html/associations.html#assoc-unidirectional-join-12m(注意映射中的unique = true)
答案 1 :(得分:0)
为了在列“order
”上定义唯一约束,此列显然存在于相应的表中。所以你无法摆脱引用和保持约束
您可以做的只是在Player
中仅存储AvatarAttributeOwnership
的主键,但为什么要这样做?如果您想知道为创建AvatarAttributeOwnership实例而加载Player实例的任何开销:您可以始终传递em.getReference(Player.class, playerId)
而不是不触发数据库选择的真实播放器实例,除非您访问任何播放器状态AvatarAttributeOwnership的构造函数。
答案 2 :(得分:0)
原来我想要的是AvatarAttributeOwnership
@Embeddable
。