Hibernate получает NULL в сопоставлении внешнего ключа @oneToone - PullRequest
0 голосов
/ 10 января 2020

У меня есть связь между двумя классами, например:

Smartlist -> smartlistId` - это PK

AccountEmailing -> smartlistId FK, PK

В таблице AccountEmailing может отсутствовать исходная ссылочная запись, но позже в ней может быть запись

Я использую только хранилище таблиц smartlist

Я попытался cascade.ALL, но получил нулевое значение в таблице идентификаторов FK

Я попробовал следующий код, который работает со следующей комбинацией,

  • исходные данные с smartlist и AccountEmailing

Это работает Я получаю запись в обеих таблицах, но позже обновляю запись выдает ошибку, так как AccountEmailing уже имеет запись (CascadeType.PERSIST позволяет только вставку, а не обновление для ребенка)

  • исходные данные со смарт-списком и без данных в AccountEmailing

означает, что это не создаст запись в AccountEmailing, но позже добавив запись, он создает оператор вставки для AccountEmailing, и со следующего раза он всегда обновляет

Я ищу решение, как я могу обновить свой класс, чтобы я мог выполнить CRUD для AccountEmailing:

public class Smartlist {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "smartlistId")
    private Integer smartlistId;

    @OneToOne( mappedBy = "smartlist", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST, orphanRemoval = true)
    private AccountEmailing accountEmailing;
}

@Entity
@Table(name = "account_emailing")
public class AccountEmailing implements Serializable {

    @Id
    @OneToOne
    @JoinColumn(name = "smartlistId")
    private Smartlist smartlist;

}

1 Ответ

1 голос
/ 10 января 2020

Используйте эти измененные сущности. Вам нужно @MapsId вместе с установщиком в сущности умного списка.

@Entity
public class Smartlist {

        @Id
        @GeneratedValue(strategy= GenerationType.AUTO)
        @Column(name = "smartlistId")
        private Integer smartlistId;

        @OneToOne( mappedBy = "smartlist", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
        private AccountEmailing accountEmailing;

        String name;

    public Integer getSmartlistId() {
        return smartlistId;
    }

    public void setSmartlistId(Integer smartlistId) {
        this.smartlistId = smartlistId;
    }
    public String getName() {
        return name;
    }

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

    public void addAccountEmail(AccountEmailing emailing)
    {
        accountEmailing=emailing;
        accountEmailing.setSmartlist(this);
    }


}



@Entity
@Table(name = "account_emailing")
public class AccountEmailing implements Serializable {

    @Id
    @Column(name="smartlistId")
    Integer id;

    @MapsId
    @OneToOne
    @JoinColumn(name = "smartlistId")
    private Smartlist smartlist;

    String name;

    public Smartlist getSmartlist() {
        return smartlist;
    }

    public void setSmartlist(Smartlist smartlist) {
        this.smartlist = smartlist;
    }

    public String getName() {
        return name;
    }

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

    public Integer getId() {
        return id;
    }

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

Используйте следующий код, чтобы связать сущности

 Smartlist smartlist=new Smartlist();
 smartlist.setName("SmartList");

 AccountEmailing accountEmailing=new AccountEmailing();
 accountEmailing.setName("AccountEmailing");

 smartlist.addAccountEmail(accountEmailing);

 smartListRepo.saveAndFlush(smartlist);

при обновлении нужно брать ссылку из родительского объекта, иначе он не будет работать, так как будет создавать новый объект каждый раз

, поэтому для вставки выше все в порядке, для обновления необходимо применить

Smartlist smartlist = smartlistRepository.findOne(smartlistDTO.getSmartlistId());
// take an existence reference
AccountEmailing accountEmailing = smartlist.getAccountEmailing();
// perform update on accountEmailing
smartlist.setAccountEmailing(accountEmailing);
smartlistRepository.save(smartlist);

Аннотация @MapsId указывает Hibernate использовать значение первичного ключа родительского объекта в качестве первичного ключа дочернего объекта.

...