Reputation: 1334
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
andAccountEmailing
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;
}
Upvotes: 0
Views: 503
Reputation: 691
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.
Upvotes: 1