thomas
thomas

Reputation: 1271

Spring Data : issue with OneToMany, child not saved properly

I am having trouble dealing with @OneToMany relationship.

Here is my code :

@Entity
@Table(name = "type_mouvement")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class TypeMouvement implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(mappedBy="typeMouvement", fetch = FetchType.EAGER,cascade = CascadeType.PERSIST)
    private List<CompteTypeMouvement> comptes;
...
}

@Entity
@Table(name = "type_mouvement_comptes")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class CompteTypeMouvement implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String numCompte;

    @ManyToOne
    private TypeMouvement typeMouvement;
...
}

How I use these entities :

TypeMouvement typeMouvementFromDB = typeMouvementRepository.findOne(new Long(1));
CompteTypeMouvement compte = new CompteTypeMouvement();
compte.setNumCompte("123");
compte.setTypeMouvement(typeMouvementFromDB);
typeMouvementFromDB.getComptes().add(compte);
typeMouvementRepository.save(typeMouvementFromDB);

The result I get :

enter image description here

I thought I would get :

enter image description here

Why are the properties of CompteTypeMouvement not filled when I save TypeMouvement?

Upvotes: 2

Views: 2969

Answers (1)

Maciej Kowalski
Maciej Kowalski

Reputation: 26522

You are trying to invoke save passing an already existing entity:

TypeMouvement typeMouvementFromDB = typeMouvementRepository.findOne(new Long(1));
typeMouvementRepository.save(typeMouvementFromDB);

The relationship has a persist cascade type only though:

@OneToMany(mappedBy="typeMouvement", fetch = FetchType.EAGER,cascade = CascadeType.PERSIST)
private List<CompteTypeMouvement> comptes;

The save impl is a follows (spring-data-jpa-1.11.3):

public <S extends T> S save(S entity) {

    if (entityInformation.isNew(entity)) {
        em.persist(entity);
        return entity;
    } else {
        return em.merge(entity);
    }
}

Which means that a merge instead of a persist will be invoked.

This if you add merge to cascade it should work:

@OneToMany(mappedBy="typeMouvement", fetch = FetchType.EAGER,
  cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<CompteTypeMouvement> comptes;

Upvotes: 3

Related Questions