Hibernate @ManyToMany отношения с составными ключами, которые разделяют свойство - PullRequest
0 голосов
/ 06 июля 2018

Итак, я работаю с базой данных, которая использует много составных ключей. Я пытаюсь использовать JPA / Hibernate, чтобы настроить JoinTable для одного из отношений. Вот урезанный пример того, что делается

Родительский класс

@Entity
@Table(name = "PROTAGONIST")
public class Protagonist {
    private Integer id;
    private String name;

    @Id
    @Column(name = "id", nullable = false)
    public Integer getId() {return id;}

    public void setId(Integer id) { this.id = id;}

    @Column(name = "pro_name", nullable = false, length = 50)
    public String getName() {return name;}

    public void setName(String name) { this.name = name;}
}

Идентификационный номер класса

@Embeddable
public class ItemId {
    private int pId;
    private short invSlot;

    @Column(name = "P_Id", nullable = false)
    public int getpId() {return pId;}

    public void setpId(int pId) { this.pId = pId;}

    @Column(name = "Inv_SlotNum", nullable = false)
    public short getInvSlot() {return invSlot;}

    public void setInvSlot(short invSlot) { this.invSlot = invSlot;}
}

Класс предмета

public class Item {
    private ItemId id;
    private String itemName;
    private Double cost;
    private Set<Buff> buffs;

    @EmbeddedId
    public ItemId getId() {return id;}

    public void setId(ItemId id) { this.id = id;}

    @Column(name = "Item_Name", nullable = false, length = 100)
    public String getItemName() {return itemName;}

    public void setItemName(String name) { this.itemName = name;}

    @Column(name = "Item_Cost")
    public Double getCost() {return cost;}

    public void setCost(Double cost) { this.cost = cost;}

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "BUFFSONITEMS",
        joinColumns = {
            @JoinColumn(name = "P_Id", referencedColumnName = "P_Id"),
            @JoinColumn(name = "Inv_SlotNum", referencedColumnName = "Inv_SlotNum")
        },
        inverseJoinColumns = {
            @JoinColumn(name = "P_Id", referencedColumnName = "P_Id"),
            @JoinColumn(name = "Buff_SlotNum", referencedColumnName = "Buff_SlotNum")
        }
    )
    public Set<Buff> getBuffs() {return buffs;}

    public void setBuffs(Set<Buff> buffs) { this.buffs = buffs;}
}

Buff ID Class

@Embeddable
public class BuffId {
    private Integer pId;
    private Short buffSlotNum;

    @Column(name = "P_Id", nullable = false)
    public Integer getpId() {return pId;}

    public void setpId(Integer pId) { this.pId = pId;}

    @Column(name = "Buff_SlotNum", nullable = false)
    public Short getBuffSlotNum() {return buffSlotNum;}

    public void setBuffSlotNum(Short buffSeqNum) { this.buffSlotNum = buffSeqNum;}
}

Класс баффа

@Entity
@Table(name = "BUFF")
public class Buff {
    private BuffId id;
    private String buffName;
    private Long duration;
    private Set<Item> buffedItems;

    @EmbeddedId
    public BuffId getId() {return id;}

    public void setId(BuffId id) { this.id = id;}

    @Column(name = "Buff_Name", nullable = false, length = 100)
    public String getBuffName() {return buffName;}

    public void setBuffName(String name) { this.buffName = name;}

    @Column(name = "Duration", nullable = false)
    public Long getDuration() {return duration;}

    public void setDuration(Long duration) { this.duration = duration;}

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "BUFFSONITEMS",
        joinColumns = {
            @JoinColumn(name = "P_Id", referencedColumnName = "P_Id"),
            @JoinColumn(name = "Buff_SlotNum", referencedColumnName = "Buff_SlotNum")
        },
        inverseJoinColumns = {
            @JoinColumn(name = "P_Id", referencedColumnName = "P_Id"),
            @JoinColumn(name = "Inv_SlotNum", referencedColumnName = "Inv_SlotNum")
        }
    )
    public Set<Item> getBuffedItems() {return buffedItems;}

    public void setBuffedItems(Set<Item> buffedItems) { this.buffedItems = buffedItems;}
}

Всякий раз, когда я пытаюсь запустить Spring Boot, я получаю следующее исключение org.hibernate.MappingException: повторяющийся столбец в сопоставлении для коллекции: столбец com.blankd.composite.key.Item.buffs: P_Id . Таблица BUFFSONITEMS использует все 3 столбца как часть первичного ключа для каждой строки в этой таблице. Все три столбца также имеют ограничения на соответствующие таблицы для соответствующих таблиц. Это означает, что P_Id имеет ограничение подделки ключа как для Buff, так и для Item.

Я не уверен, что делаю неправильно, так как мне нужен P_Id для уникальной идентификации строки в каждой таблице.

1 Ответ

0 голосов
/ 06 июля 2018

Вы должны выбрать одну сторону отношения «многие ко многим», чтобы стать «владельцем». «Обратная» сторона должна затем использовать элемент mappedBy.

Если бы вы выбрали Item.buffs как сторону-хозяина, вы бы отобразили Buff.buffedItems следующим образом:

    @ManyToMany(mappedBy="buffs")
    public Set<Item> getBuffedItems() {return buffedItems;}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...