Избавление от лишней ссылки на владельца в JPA - PullRequest
2 голосов
/ 08 июля 2011

У меня есть эти объекты в 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, сохранив определенное там ограничение уникальности?

Ответы [ 3 ]

0 голосов
/ 09 июля 2011

Чтобы определить уникальное ограничение для столбца 'order', этот столбец, очевидно, должен присутствовать в соответствующей таблице.Таким образом, вы не можете избавиться от ссылок и , сохраняя ограничение.
Что вы можете сделать, это сохранить только первичный ключ Player в AvatarAttributeOwnership, но зачем вам это?В случае, если вас интересуют какие-либо накладные расходы на загрузку экземпляра Player для создания экземпляра AvatarAttributeOwnership: вы всегда можете передать em.getReference(Player.class, playerId) вместо реального экземпляра Player, который не вызывает выбор базы данных, если вы не обращаетесь к какому-либо состоянию Player в конструктореAvatarAttributeOwnership.

0 голосов
/ 21 июля 2011

Получается, что я действительно хотел сделать AvatarAttributeOwnership @Embeddable.

0 голосов
/ 08 июля 2011

Вы можете, определив однонаправленную связь много-к-одному.Это создаст таблицу соединения со столбцом для идентификатора владельца (Player в вашем случае) и другой столбец с идентификатором дочерних элементов (AvatarAttributeOwnership).См. http://docs.jboss.org/hibernate/core/3.3/reference/en/html/associations.html#assoc-unidirectional-join-12m для объяснения (обратите внимание на уникальный = true в отображении)

...