Getting errors while trying to persist child entity (MsgRetry) when trying to get an entity of parent entity (Msg) where the parent PK (msg_id) is the FK in the child entity.
Errors like: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property
The parent entity, does not need to know about the child entity (at least i don't think it needs to, to work). Once the child entity is persisted I'm trying to also persist the parent entity. I can work around this by not having the parent entity in the child entity and the call the associated repositories. However, I don't think it's as clean as what I'm attempting but obviously more difficult/ complex.
Thanks for any advice on best practices or how to achieve this if this is a good solution.
tables:
| msg | |
|---|---|
| msg_id | pk |
| msg_status | msg_status |
| msg_retry | |
|---|---|
| msg_id | fk |
| count | |
| timestamp |
model:
@Entity
@Table(name="msg")
public class Msg {
@Id
@Column(name = "msg_id")
@GeneratedValue(strategy = generationtype.sequence, generator = "msg_id_seq_gen")
@SequenceGenerator(name = "msg_id_seq_gen", sequencename = "msg_id_seq", allocationsize = 1)
private Long msgId;
@Column(name = "msg_status", nullable = false)
private String msgStatus;
...
//getters setters
}
@Entity
@Table(name = "msg_retry")
public class MsgRetry {
@Id
@Column(name = "msg_id") //fk
private Long msgId;
@Column(name = "count")
private Long count;
@Generated(value = GenerationTime.ALWAYS)
@Column(name = "timestamp")
private Date timestamp;
@JoinColumn(name = "msg_id")
@ManyToOne(targetEntity = Msg.class, fetch = FetchType.LAZY)
private Msg msg;
public Msg getMsg() { return msg; }
public void setMsg(Msg msg) { this.msg = msg; }
}
public class BizLogic {
MsgRetryRepository retryRepo
public MsgRetry retry(Long msgId, String msgStatus) {
MsgRetry mr = retryRepo.findById(msgId)
if (mr !=null) {
mr.set....
mr.setMsg(mr.getMsg().setMsgStatus("XX"));
...
retryRepo.save(mr);
}
}
}
CodePudding user response:
how about add one id fields to MsgRetry class
CodePudding user response:
First, straighten out your IDs for MsgRetry. The FK should be good enough.
@Entity
@Table(name = "msg_retry")
public class MsgRetry {
@Id
@ManyToOne(optional = false)
@JoinColumn(name = "msg_id")
private Msg msg;
@Column(name = "count")
private Long count;
@Generated(value = GenerationTime.ALWAYS)
@Column(name = "timestamp")
private Date timestamp;
public Msg getMsg() { return msg; }
public void setMsg(Msg msg) { this.msg = msg; }
}
Next, be sure MsgRetryRepository is properly sub-classed:
public interface MsgRetryRepository extends CrudRepository<MsgRetry, Msg>
{
// Empty for now
}
Lastly, query the MsgRetry in the right way:
public class BizLogic {
MsgRetryRepository retryRepo
public MsgRetry retry(Msg msg, String msgStatus) {
MsgRetry mr = retryRepo.findById(msg);
if (mr !=null) {
// XXX I cannot tell from your logic what you are doing here.
retryRepo.save(mr);
}
}
}
What is your persistence layer? Maybe you can turn on debugging and visit the logs to see what is happening under the hood.
