0

I have a relation between two class like this:

Smartlist -> smartlistId` is PK

AccountEmailing -> smartlistId FK,PK

AccountEmailing table might not have an initial reference record but later it could have a record

I am only using smartlist table repository

I had tried cascade.ALL but getting null in FK table id

I have tried the following code which is working with the following combination,

  • initial data with smartlist and AccountEmailing

This is working I am getting a record in both the tables but later updating a record giving me an error as AccountEmailing already has an entry (CascadeType.PERSIST only allows insert not update for child)

  • initial data with smartlist and no data in AccountEmailing

means it will not create an entry in AccountEmailing but later adding a record it creating an insert statement for AccountEmailing and from next time it always updates

I am looking for a solution that how can I update my class so I can perform CRUD on 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;

}
Navin Gelot
  • 1,264
  • 3
  • 13
  • 32
  • 1
    See this if it helps.You need @MapsId https://stackoverflow.com/questions/59282221/hibernate-map-id-automatically-from-field/59440796#59440796 – user06062019 Jan 10 '20 at 13:55
  • *I have tried the following code *: which code? Post the code, tell precisely what you expect it to do, and what it does instead. – JB Nizet Jan 10 '20 at 13:57

1 Answers1

1

Use these modified entities.You need @MapsId along with a setter in the smartlist entity.

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

Use the following code to associate the entities

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

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

 smartlist.addAccountEmail(accountEmailing);

 smartListRepo.saveAndFlush(smartlist);

when updating we have to took reference from the parent object otherwise it will not work as it will going to create a new object each time

so, For insert above is fine, for update following need to apply

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

The @MapsId annotation tells Hibernate to use the primary key value of parent entity as primary key of child entity.

Navin Gelot
  • 1,264
  • 3
  • 13
  • 32
user06062019
  • 681
  • 4
  • 9