Новая таблица Создана для обновления существующей. Отображение OneToMany с помощью CompositeKey, Springboot, Hibernate - PullRequest
1 голос
/ 11 января 2020

У меня есть две таблицы в моей схеме, имеющие отношение один ко многим.

unit и unit_bridge

unit имеет 2 столбца id и name

unit_bridge имеет два столбца: unit_master_id и unit_slave_id . Они оба вместе образуют составной ключ . Здесь unit_slave_id является внешним ключом для id столбца в единице.

Когда я получаю POST запрос, создается новая таблица с именем unit_child_units в базе данных. и unit_bridge обновляется с неправильными значениями для столбца unit_slave_id . Хотя значения unit_master_id являются правильными в таблице unit_bridge, это соответствует unit_slave_id отображение неверно.

Я не хочу новую таблицу, вместо этого я хочу обновить мою unit_bridge table, так как я получаю POST-запрос от пользователя для unit table.

Вот мой json запрос,

{
"name" : "john doe",
"childUnits" : [
               {

               "unitBridgeId" :{
                  "unit_master_id" : 4
                }
             }
          ]

}

Вот мои модели.

шт. java



import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

@Entity
@Table(name="unit")
@JsonInclude(Include.NON_NULL)
public class Unit implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String name;

    @Transient
    private int parent_id;

    @OneToMany(cascade=CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private Set<UnitBridge> childUnits = new HashSet<UnitBridge>();

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public int getParent_id() {
        return parent_id;
    }

    public void setParent_id(int parent_id) {
        this.parent_id = parent_id;
    }

    public Set<UnitBridge> getChildUnits() {
        return childUnits;
    }

    public void setChildUnits(Set<UnitBridge> childUnits) {
        this.childUnits = childUnits;
    }

    @Override
    public String toString() {
        return "Unit [id=" + id + ", name=" + name + ", parent_id=" + parent_id + ", childUnits=" + childUnits + "]";
    }

}

UnitBridge. java



import java.io.Serializable;

import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

@Entity
@Table(name="unit_bridge")
@JsonInclude(Include.NON_NULL)
public class UnitBridge implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private UnitBridgeId unitBridgeId;

    @Override
    public String toString() {
        return "UnitBridge [unitBridgeId=" + unitBridgeId + "]";
    }

    public UnitBridgeId getUnitBridgeId() {
        return unitBridgeId;
    }

    public void setUnitBridgeId(UnitBridgeId unitBridgeId) {
        this.unitBridgeId = unitBridgeId;
    }


    public int getUnit_master_id() {
        return unitBridgeId.getUnit_master_id();
    }

    public int getUnit_slave_id() {
        return unitBridgeId.getUnit_slave_id();
    }

    public void setUnit_master_id(int unit_master_id) {
        unitBridgeId.setUnit_master_id(unit_master_id);
    }
    public void setUnit_slave_id(int unit_slave_id) {
        unitBridgeId.setUnit_slave_id(unit_slave_id);
    }
}

UnitBridgeId. java

import java.io.Serializable;

import javax.persistence.Embeddable;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

@Embeddable
public class UnitBridgeId implements Serializable {


    private static final long serialVersionUID = 1L;

    private int unit_master_id;

    private int unit_slave_id;

    public UnitBridgeId() {

    }

    public UnitBridgeId(int unit_master_id, int unit_slave_id) {
        this.unit_master_id = unit_master_id;
        this.unit_slave_id=unit_slave_id;
    }

    public int getUnit_master_id() {
        return unit_master_id;
    }

    public void setUnit_master_id(int unit_master_id) {
        this.unit_master_id = unit_master_id;
    }

    public int getUnit_slave_id() {
        return unit_slave_id;
    }

    public void setUnit_slave_id(int unit_slave_id) {
        this.unit_slave_id = unit_slave_id;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + unit_master_id;
        result = prime * result + unit_slave_id;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        UnitBridgeId other = (UnitBridgeId) obj;
        if (unit_master_id != other.unit_master_id)
            return false;
        if (unit_slave_id != other.unit_slave_id)
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "UnitBridgeId [unit_master_id=" + unit_master_id + ", unit_slave_id=" + unit_slave_id + "]";
    }

}

1 Ответ

0 голосов
/ 11 января 2020

Я думаю, что это идеальный пример, где нам нужно использовать аннотацию @IdClass вместо @Embeddable для составного ключа.

@Entity
@Table(name="unit")
public class Unit implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String name;

    @Transient
    private int parent_id;

    @OneToMany(mappedBy = "unit_slave_id", cascade = CascadeType.ALL)
    private Set<UnitBridge> childUnits = new HashSet<UnitBridge>();

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public int getParent_id() {
        return parent_id;
    }

    public void setParent_id(int parent_id) {
        this.parent_id = parent_id;
    }

    public Set<UnitBridge> getChildUnits() {
        return childUnits;
    }

    public void setChildUnits(Set<UnitBridge> childUnits) {
        this.childUnits = childUnits;
    }

    @Override
    public String toString() {
        return "Unit [id=" + id + ", name=" + name + ", parent_id=" + parent_id + "]";
    }


    public static void main(String[] args) {


        SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();

        Unit unit = new Unit();
        unit.setName("A");

        session.save(unit);

        Set<UnitBridge> unitBridges = new HashSet<>();
        {
            UnitBridge unitBridge = new UnitBridge();
            unitBridge.setUnit_master_id(100);
            unitBridge.setUnit_slave_id(unit);
            unitBridges.add(unitBridge);
        }
        {
            UnitBridge unitBridge = new UnitBridge();
            unitBridge.setUnit_master_id(200);
            unitBridge.setUnit_slave_id(unit);
            unitBridges.add(unitBridge);
        }
        unit.setChildUnits(unitBridges);

        transaction.commit();

//        Unit unit = session.get(Unit.class,1);
//        System.out.println(unit.getId());
//        System.out.println(unit.getChildUnits().iterator().next().getUnit_master_id());

        session.close();
    }
}
@Entity
@Table(name="unit_bridge")
@IdClass(UnitBridgeId.class)
public class UnitBridge implements Serializable{
    private static final long serialVersionUID = 1L;

    @Id
    private int unit_master_id;

    @ManyToOne
    @Id
    private Unit unit_slave_id;

    public int getUnit_master_id() {
        return unit_master_id;
    }

    public void setUnit_master_id(int unit_master_id) {
        this.unit_master_id = unit_master_id;
    }

    public Unit getUnit_slave_id() {
        return unit_slave_id;
    }

    public void setUnit_slave_id(Unit unit_slave_id) {
        this.unit_slave_id = unit_slave_id;
    }
}
public class UnitBridgeId implements Serializable {
    private static final long serialVersionUID = 1L;

    private int unit_master_id;

    private Unit unit_slave_id;

    public UnitBridgeId(){

    }
    public UnitBridgeId(int unit_master_id, Unit unit_slave_id) {
        this.unit_master_id = unit_master_id;
        this.unit_slave_id = unit_slave_id;
    }

    public int getUnit_master_id() {
        return unit_master_id;
    }

    public void setUnit_master_id(int unit_master_id) {
        this.unit_master_id = unit_master_id;
    }

    public Unit getUnit_slave_id() {
        return unit_slave_id;
    }

    public void setUnit_slave_id(Unit unit_slave_id) {
        this.unit_slave_id = unit_slave_id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UnitBridgeId that = (UnitBridgeId) o;
        return unit_master_id == that.unit_master_id &&
                Objects.equals(unit_slave_id, that.unit_slave_id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(unit_master_id, unit_slave_id);
    }

    @Override
    public String toString() {
        return "UnitBridgeId [unit_master_id=" + unit_master_id + ", unit_slave_id=" + unit_slave_id + "]";
    }

}

Таблицы, созданные Hibernate

Hibernate: create table unit (id integer not null, name varchar(255), primary key (id)) engine=MyISAM
Hibernate: create table unit_bridge (unit_master_id integer not null, unit_slave_id_id integer not null, primary key (unit_master_id, unit_slave_id_id)) engine=MyISAM
Hibernate: alter table unit_bridge add constraint FKgv4psic91eix7b780lekkrdg4 foreign key (unit_slave_id_id) references unit (id)

таблица единиц измерения
enter image description here

таблица единиц измерения

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...