我正在尝试更新数据,正如我所知保存()方法在id为null时保存实体,或者在DB中找到给定的id时更新数据库中的现有实体。
但是,当我尝试保存数据时,它不会更新:
public Employer update() {
Employer emp = Employer.builder()
.id(2L) // it exists in database
.name('new company name')
.build();
return repository.save(emp);
}
但是,当我从数据库中检索数据并更新其字段并再次保存时,它会更新:
public Employer update() {
Employer emp = repository.getOne(2L);
emp.setName('new company name');
return repository.save(emp);
}
有人能解释一下这种行为的原因吗?我读了文档,但找不到任何与此相关的内容。
以下是我的repository:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface Employer extends JpaRepository<Employer, Long> {
}
和实体:
@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(schema = "public", name = "employer")
public class Employer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
@Size(max = 50)
private String name;
}
4条答案
按热度按时间s4chpxco1#
您的实体
Employer
看起来处于分离/ transient 状态,您正在手动传递id
值,这是不允许的,因为它被标记为@GeneratedValue(strategy = GenerationType.IDENTITY)
。你需要做的是当你知道主键值i的时候e
id
值,首先使用findById()方法从数据库中获取实体,通过该方法,实体进入托管状态,然后尝试通过调用保存()方法更新实体。这将更新您的实体。有关实体状态的更多信息,您可以参考以下内容:https://vladmihalcea.com/a-beginners-guide-to-jpa-hibernate-entity-state-transitions/
rqqzpn5f2#
要通过JPA更新现有实体对象,应该首先使实体管理器可用。
通读这篇文章
https://www.objectdb.com/java/jpa/query/jpql/update
摘录自同一
我假设在没有发生更新的情况下,实体还不是托管实体。
更多关于托管实体: www.example.com
6vl6ewon3#
这可以根据 transient 和持久/托管实体来回答。
临时实体:创建了一个新的实体对象,到目前为止它还没有与任何会话相关联。此对象与数据库中的任何存储数据无关,因为它是新创建的。
当你从数据库中提取一条记录时,它是以托管或持久状态被提取的,对它所做的任何更改都将反映回它所Map到的记录。
建议一:不应手动添加主键值,因为它已自动递增。
建议二:如果你已经有了recirds id,先从db中获取它,然后再更新它。
以下是关于该主题的Stackoverflow讨论,以获得更多见解:What are detached, persistent and transient objects in hibernate?
4si2a6ki4#
我也面临着同样的问题。问题是,如果新数据与旧数据相同,JPA不会更新您的数据。如果修改后的数据没有任何变化,则不会运行更新查询。