Search code examples
javamysqljpaeclipselinkone-to-many

How to avoid persisting new object when oneToMany connection?


enter image description here

There is a three lines in returnreason-table and I don't want more lines there. User just choose one of the three reasons and I want only id to rma-table. Now it inserts a new line to reason-table every time when inserting new rma. I can take relation off between the tables but I wonder if there is better solution to avoid inserting new lines when persisting rma object? If I take cascadeType off from the class Rma, it is not helping/working. Then I got an error message, that jpa found an object, which is not persisted or something like that.

errormessage if I took cascadetype.ALL off

java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: com.entity.Returnreason[ returnreasonId=null ].

public class Rma implements Serializable {
@ManyToOne(cascade = CascadeType.ALL)
private Returnreason returnreasonReturnreasonId;

public class Returnreason implements Serializable {
@OneToMany(mappedBy = "returnreasonReturnreasonId", cascade = CascadeType.ALL)
private Collection<Rma> rmaCollection;

Solution

  • JPA methods require that the model use managed entities, while you seem to be attempting to associate a managed entity to something outside the context. This is a bad practice, and JPA is required to throw exceptions as it cannot tell what you intend it to do with the unmanaged instance.

    You have two options

    1. Read in your 3 Returnreason and use those entities for merging. If there really are only ever 3, you can change your caching options so they are always in the cache, so that an em.find operation doesn't have to hit the database.
    2. Remove the mapping in your Rma class to the Returnreason class and map the returnreasonReturnreasonId field as a basic mapping. You then can set the value in the Rma entity directly

    The first option is probably the most frequently used, and really is required since you should have been maintaining the Returnreason rmaCollection anyway everytime you add a new Rma instance. While it may seem like you only need to set the Rma.returnreasonReturnreasonId, these are java objects, and your application is responsible for maintaining both sides of bidirectional relationships.