JPA @GeneratedValue和@Id

时间:2016-11-15 08:14:03

标签: java jpa

在我的实体中有一个名为id的字段,标有@Id(我手动设置)并且知道我想知道,是否有可能自动生成唯一ID(使用@GeneratedValue)但我也想要手动设置ID,未设置时,应自动生成。

示例:

@Id
@GeneratedValue
private long id;

创建实体

new Entity(someid) //Once with ID and no generated value
new Entity() //Second without ID and generated unique value

我希望你能理解我。

1 个答案:

答案 0 :(得分:2)

我不认为这会奏效。 JPA会自动生成您的ID值,并负责@GeneratedValue。问问自己'如果已经存在ID为100的现有实体会发生什么。我手动创建一个名为100'的新实体。直觉上我会说JPA(或实现)会引发预期。

在写上面的答案时,我想到了编写自己的生成器(根本没有尝试过,只是在stackoverflow上编码。

您可以将自己的生成器实现传递给@GeneratedValue注释

@Id
@GeneratedValue(startegy = GenerationType.IDENTITY, generator="generatedIdOrCustomId")
@GenericGenerator(name="generatedIdOrCustomId", strategy="GeneratedIdOrCustomId")
private Long id;
...

自定义实现应如下所示:

public class GeneratedIdOrCustomId extends IdentityGenerator {

@Override
public Serializable generate(SessionImplementor session, Object obj) throws HibernateException {
    if (((YourEntity) obj).getId() == null) {
        // the id is null, let JPA create an id.
        return super.generate(session, obj);
    } else {
        // the id is set and should not be generated by JPA.
        return ((YourEntity) obj).getId();
    }
}

generate方法只是一个快速而又脏的实现。在这种情况下,您还必须检查obj == null是否(Hibernate)Exception并抛出$kernel = new AppKernel('prod', false); $kernel->loadClassCache(); $kernel = new AppCache($kernel);