您好我是 Sprig Data JPA 的新手,我很想知道即使我将Id传递给实体,Spring数据jpa也会插入而不是合并。当我实现 Persistable 接口并实现这两个方法时,我想:
public Long getId();
public Boolean isNew();
它将自动合并而不是持久。
我有一个名为User的实体类:
@Entity
@Table(name = "T_USER")
public class User implements Serializable, Persistable<Long> {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "USER_ID")
private Long id;
@Column(name = "CREATION_TIME", nullable = false)
private Date creationTime;
@Column(name = "FIRST_NAME", nullable = false)
private String firstName;
@Column(name = "LAST_NAME", nullable = false)
private String lastName;
@Column(name = "MODIFICATION_TIME", nullable = false)
private Date modificationTime;
还有另一个班级
@Entity
@Table(name = "T_USER_ROLE")
public class UserRole implements Serializable, Persistable<Long> {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long roleId;
@Column(name = "ROLE_NAME")
private String userRole;
}
我有一个名为UserRepostory的自定义存储库,扩展了JpaReopistory。我正在点击合并和保存,因为我看到实现证明Spring Data Jpa使用以上两种方法来更新或插入。
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
我一直想弄清楚,但没有得到任何线索。可能是你 伙计们可以提供帮助。
答案 0 :(得分:35)
我遇到了这个问题,尝试实现Persistable
无济于事,然后查看了Spring Data JPA源代码。我不一定会在您的示例代码中看到这一点,但我的实体中有一个@Version
字段。如果存在@Version
字段,Spring Data将测试该值以确定该实体是否为新实体。如果@Version
字段不是原始字段且为null,则该实体被视为新实体。
这让我在测试中花了很长时间,因为我没有在我的表示中设置版本字段,而只在持久化实体上设置。我也没有在其他有用的Spring Data文档中看到这一点(这是另一个问题......)。
希望能帮助别人!
答案 1 :(得分:3)
默认情况下,Spring Data JPA会检查给定实体的identifier属性。如果标识符属性为null
,则该实体将被假定为新实体,否则将不是新实体。这是Id-Property inspection
Reference
如果您使用带有EntityManeger
{Spring} .merge()
的Spring JPA,则会更新您的内容,.persist()
将会插入。
@PersistenceContext
private EntityManager em;
@Override
@Transactional
public User save(User user) {
if (user.getId() == null) {
em.persist(user);
return user;
} else {
return em.merge(user);
}
}
无需实现Persistable
接口。