Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 消除JPA中对所有者的冗余引用_Java_Hibernate_Jpa_Entity Relationship - Fatal编程技术网

Java 消除JPA中对所有者的冗余引用

Java 消除JPA中对所有者的冗余引用,java,hibernate,jpa,entity-relationship,Java,Hibernate,Jpa,Entity Relationship,我在JPA+Hibernate、Player和AvatarAttributeOwnership中拥有这些实体。前者有后者的集,定义了它拥有的化身属性 @Entity public class Player implements Serializable { @Id @GeneratedValue private long id; @OneToMany(fetch=FetchType.LAZY,mappedBy="owner",cascade=Cascade

我在JPA+Hibernate、
Player
AvatarAttributeOwnership
中拥有这些实体。前者有后者的
集,定义了它拥有的化身属性

@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;
    }

}

我是否可以在保留此处定义的唯一约束的同时,删除
AvatarAttributeOwnership
中的所有者引用?

您可以通过定义单向多对一关联。这将生成一个连接表,其中一列为所有者id(在您的情况下为玩家),另一列为子级id(AvatarAttributeOwnership)。请参阅以获取解释(请注意映射中的unique=true)

您可以通过定义单向多对一关联。这将生成一个连接表,其中一列为所有者id(在您的情况下为玩家),另一列为子级id(AvatarAttributeOwnership)。请参阅以获取解释(请注意映射中的unique=true)

为了定义列“
顺序”
”的唯一约束,该列显然必须出现在相应的表中。因此,您无法摆脱引用并保留约束。

您可以做的是只将
Player
的主键存储在
AvatarAttributeOwnership
中,但为什么要这样做呢?如果您想知道为创建AvatarAttributeOwnership实例而加载播放器实例的开销:您可以始终传递
em.getReference(Player.class,playerId)
而不是真正的玩家实例,除非您访问AvatarAttributeOwnership构造函数中的任何玩家状态,否则它不会触发数据库选择。

为了在列“
order
”上定义唯一约束,该列显然必须出现在相应的表中。因此,您无法摆脱引用并保留约束。

您可以做的是只将
Player
的主键存储在
AvatarAttributeOwnership
中,但为什么要这样做呢?如果您想知道为创建AvatarAttributeOwnership实例而加载播放器实例的开销:您可以始终传递
em.getReference(Player.class,playerId)
而不是真正的玩家实例,它不会触发数据库选择,除非你访问AvatarAttributeOwnership构造函数中的任何玩家状态。

结果证明我真正想要的是使
AvatarAttributeOwnership
@Embeddeble
结果证明我真正想要的是使
AvatarAttributeOwnership
@embeddeble

我可能把示例代码缩写得太多了。巴特:注意,我提到的关联类型与你的不同:它是多对多的,unique=true。我自己按照我提供的链接中的描述使用了它,并且我不必在children中保留owner属性。我只需要在owner中定义关系:owner o1=new owner();o1.children.add(newchild());Child没有任何所有者引用,它按预期工作。我可能对示例代码进行了太多的缩写。巴特:注意,我提到的关联类型与你的不同:它是多对多的,unique=true。我自己按照我提供的链接中的描述使用了它,并且我不必在children中保留owner属性。我只需要在owner中定义关系:owner o1=new owner();o1.children.add(newchild());子项没有任何所有者引用,它按预期工作。唯一的约束是防止玩家两次拥有同一属性。然而,困难在于每个属性都由3个值定义,而不是一个值。但是,您怎么能期望能够在没有以任何方式映射的列上定义约束呢?毕竟JPA是关于O/R映射的……事实证明我真正想要的是使
AvatarAttributeOwnership
可嵌入,并在
Player
中收集它。生成一个带有列
Player\u id
的表,而不在类中。唯一性由
Set
equals
处理,而不是由数据库处理,这是正常的,但并不理想。请参阅以获取新代码。唯一约束用于防止玩家两次拥有同一属性。然而,困难在于每个属性都由3个值定义,而不是一个值。但是,您怎么能期望能够在没有以任何方式映射的列上定义约束呢?毕竟JPA是关于O/R映射的……事实证明我真正想要的是使
AvatarAttributeOwnership
可嵌入,并在
Player
中收集它。生成一个带有列
Player\u id
的表,而不在类中。唯一性由
Set
equals
处理,而不是由数据库处理,这是正常的,但并不理想。有关新代码,请参阅。
                player = em.find(Player.class, playerId);
                player.getAvatarAttributeOwnership().add(new AvatarAttributeOwnership(player, attrId, gender, type, new Date())); 
                em.persist(player);