I'm wondering where the actual behaviour of Spring Data JPA is documented, as it happens to be different from what can be expected in regular JPA with an entity manager. I would be interested to find a documentation on the life-cycle of entities in Spring JPA.
For instance, suppose we have three entities, Message
, Author
and Label
. A message can have multiple labels, but only one author.
So Message is basically :
@Entity
public class Message implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
@ManyToMany
private Set<Label> labels = new HashSet<>();
@ManyToOne
private Author author;
...
}
Links are unidirectional.
Consider the following code in a service :
Author a = new Author("auteur A");
a = authorRepository.save(a);
Message msg = new Message("un message", "texte du message", a);
msg = messageRepository.save(msg);
for (int i=0; i < 10; i++) {
Label lab = new Label("label"+i);
lab = labelRepository.save(lab);
labelRepository.flush();
msg.addLabel(lab);
}
messageRepository.save(msg);
If I omit the last line (messageRepository.save(msg)
), the labels are created, but they are not really added to a message. I find this unexpected, considering the underlying technology is JPA:
The equivalent code for standard JPA with Entity manager would be:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("demo1PU");
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
Author a = new Author("auteur A");
em.persist(a);
Message msg = new Message("un message", "texte du message", a);
em.persist(msg);
for (int i=0; i < 10; i++) {
Label lab = new Label("label"+i);
em.persist(lab);
msg.addLabel(lab);
}
transaction.commit();
em.close();
emf.close();
In the entitymanager-based code, you don't need to save the message twice : as you are still in the same transaction, the message is a managed entity, and all changes to this object made while the transaction is active are also made to the database entries.
Apparently, the entities managed by Spring are a bit different from those manipulated by regular EntityManagers. But is there some explicit documentation somewhere ? The spring-data-jpa-reference.pdf
file doesn't help much.