替代使用非自动生成ID保存在JPA / Hibernate中

时间:2018-05-03 13:32:14

标签: java hibernate spring-boot jpa spring-data-jpa

我试图将一个值插入ID为String的数据库中。

@Entity
@Table(name = "xpto_version_map")
public class XptoVersionMap implements Serializable {
    @Id
    @Column(name =  "uniq_name", unique = true, nullable = false)
    private String uniq_name;
...

尝试保存新的XptoVersionMap()时:

XptoVersionMap xptoVersionMap = new XptoVersionMap();
xptoVersionMap.setUniqName("XPTO-1");
xptoVersionMap.setValue("value2");

xptoVersionMapRepository.save(xptoVersionMap);

将抛出:

org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find xxx.api.database.entity.XptoVersionMap with id XPTO-1; nested exception is javax.persistence.EntityNotFoundException: Unable to find xxx.api.database.entity.XptoVersionMap with id XPTO-1.

我尝试了不同的解决方案,但除非我可以使用本机查询来插入值,否则我无法告诉Hibernate我只想检查@Id(uniq_name)存在,如果没有插入新值而不抛出异常。

1 个答案:

答案 0 :(得分:1)

默认情况下,Hibernate是如何工作的。当您执行保存方法并且未设置ID时,它会分配自动生成的ID。如果有ID,它会尝试更新它(在您的情况下会发生什么)。

  

保存保留实体。如果没有标识符,将分配标识符   存在。如果有的话,它本质上是在进行更新。返回   生成的实体ID。

您可以使用persist和@PrePersist

来解决此问题
@PrePersist
void generateId() {
    if (uniq_name == null) {
        uniq_name = GENERATE_SOME_UNIQUE_ID_SO_IT_DOESN'T_BREAK();
    }
}

然后使用xptoVersionMapRepository.persist(xptoVersionMap);

或者您可以使用类似的东西编写自己的生成器:

@GenericGenerator(name = "my_generator", strategy = "package.CustomGenerator")
@GeneratedValue(generator = "my_generator")

然后创建一个实现IdentifierGenerator的类CustomGenerator并创建所需的方法。