Unusual behavior regarding "detached entity passed to persist" exception when trying to persist a detached object?

huangapple go评论71阅读模式
英文:

Unusual behavior regarding "detached entity passed to persist" exception when trying to persist a detached object?

问题

以下是您要翻译的内容:

我有一个简单的模型类,就像这样:

@Entity
public class User {

    @Id
    @GeneratedValue
    long id;

    @Column(unique = true)
    String name;
    

    public long getId() {
        return id;
    }


    public void setId(long id) {
        this.id = id;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }

}

我试图持久化 User 类的实例(当临时对象的 id 不为 null 时)。

我原本期望会出现 "detached entity passed to persist" 异常,然而我并没有在这段代码中得到这个异常:

User u = new User();
u.setName("u2");
u.setId(2);
repo.save(u);

在这里,id 不为 null,所以我应该会得到一个 "detached entity passed to persist" 异常。有人能解释为什么会这样吗?

英文:

I have a simple model class like this

@Entity
public class User {

	@Id
	@GeneratedValue
	long id;

	@Column(unique = true)
	String name;
	

	public long getId() {
		return id;
	}


	public void setId(long id) {
		this.id = id;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}

}

I am trying to persist instance of User class detached (when the id of the transient object is not null).

I was expecting "detached entity passed to persist" exception, however I am not getting that, for this code

User u = new User();
u.setName("u2");
u.setId(2);
repo.save(u);

Here the id is not null, I should get a detached entity passed to persist exception Can somebody explain why?

答案1

得分: 1

Spring Data并不同于JPA,而是一个用于简化使用与EntityManager和JPA相关功能的包装器或实用工具的集合(或类似物)。

这也意味着RepositoryEntityManager并不相同。那么这两者之间有什么关系呢?

如果您查看SimpleJpaRepository的源代码:
> {@link org.springframework.data.repository.CrudRepository} 接口的默认实现

您会在那里看到:

@Transactional
public <S extends T> S save(S entity) {
	if (entityInformation.isNew(entity)) {
		em.persist(entity);
		return entity;
	} else {
		return em.merge(entity);
	}
}

在追踪了一些更多的类之后,针对entityInformation.isNew(entity),会导航到AbstractPersistable和以下方法:

@Transient
public boolean isNew() {
	return null == getId();
}

它不会尝试对已设置了Id的实体进行持久化,而是执行合并操作。

英文:

Spring data is not the same as JPA but a wrapper or a collection of utilities (or so) to ease the use of JPA related stuff and EntityManager.

Meaning also that Repository is not the same as EntityManager. So how are those two related?

If you take a look at the source code of SimpleJpaRepository
> Default implementation of the {@link org.springframework.data.repository.CrudRepository} interface

you will see there:

@Transactional
public <S extends T> S save(S entity) {
	if (entityInformation.isNew(entity)) {
		em.persist(entity);
		return entity;
	} else {
		return em.merge(entity);
	}
}

Tracing after some more classes for entityInformation.isNew(entity) leads to AbstractPersistable and method:

@Transient
public boolean isNew() {
	return null == getId();
}

It will not try to persist entity that has an Id set but merge.

huangapple
  • 本文由 发表于 2020年10月19日 19:49:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/64426738.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定