Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
184 views
in Technique[技术] by (71.8m points)

java - Spring-Data JPA: save new entity referencing existing one

The question is basically the same as below one:

JPA cascade persist and references to detached entities throws PersistentObjectException. Why?

I'm creating a new entity that references an existing, detached one. Now when I save this entity in my spring data repository an exception is thrown:

org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist

if we look at the save() method in source code of spring data JPA we see:

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

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

and if we look at isNew() in AbstractEntityInformation

public boolean isNew(T entity) {

    return getId(entity) == null;
}

So basically if i save() a new entity (id == null), spring data will always call persist and hence this scenario will always fail.

This seems to be a very typical use case when adding new items to collections.

How can I resolve this?

EDIT 1:

NOTE:

This issue is NOT directly related to How to save a new entity that refers existing entity in Spring JPA?. To elaborate assume you get the request to create the new entity over http. You then extract the information from the request and create your entity and the existing referenced one. Hence they will always be detached.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I had a similar issue where I was trying to save an new entity object with an already saved entity object inside.

What I did was implemented Persistable< T > and implemented isNew() accordingly.

public class MyEntity implements Persistable<Long> {

    public boolean isNew() {
        return null == getId() &&
            subEntity.getId() == null;
    }

Or you could use AbstractPersistable and override the isNew there ofcourse.

I don't know if this will be considered a good way of handling this issue but it worked out quite good for me and besides feels very natural to do.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...