id上的JPA@GeneratedValue

id上的JPA@GeneratedValue,jpa,Jpa,在JPA中,我使用@GeneratedValue: @TableGenerator(name = "idGenerator", table = "generator", pkColumnName = "Indecator" , valueColumnName = "value", pkColumnValue = "man") @Entity @Table(name="Man") public class Man implements Serializable { @Id @Ge

在JPA中,我使用@GeneratedValue:

@TableGenerator(name = "idGenerator", table = "generator", pkColumnName = "Indecator" , valueColumnName = "value", pkColumnValue = "man")
@Entity
@Table(name="Man")
public class Man implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "idGenerator")
    @Column(name="ID")
    private long id;

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

    public Long getId(){
        return id;
    }
}
我最初将ID设置为任意值(稍后用作测试条件):

执行commit()后,man.id的预期值是多少?它应该是(-1),一个新生成的值,还是我应该期望一个异常


我想在持久化时使用该检查来检测任何异常。

设置自动生成的字段值是不相关的。它将(应该)由JPA实现根据指定的策略进行设置。

您设置自动生成的字段值是不相关的。它将(应该)由JPA实施部门根据指定的策略进行设置

执行commit()后,man.id的预期值是多少?它应该是(-1),一个新生成的值,还是我应该期望一个异常

使用
GeneratedValue
时,您只需设置
id
。persist上的行为在不同的实现中会有所不同,因此依赖此行为是一个坏主意(不可移植)

我想在持久化时使用该检查来检测任何异常

如果出现问题,JPA将抛出(的子类)。处理问题的正确方法是捕获此异常(顺便说一下,这是一个
RuntimeExeption

如果您坚持使用穷人检查,请不要分配
id
,并检查persist之后是否仍有默认值(在您的情况下,它将是
0L

执行commit()后,man.id的预期值是多少?它应该是(-1),一个新生成的值,还是我应该期望一个异常

使用
GeneratedValue
时,您只需设置
id
。persist上的行为在不同的实现中会有所不同,因此依赖此行为是一个坏主意(不可移植)

我想在持久化时使用该检查来检测任何异常

如果出现问题,JPA将抛出(的子类)。处理问题的正确方法是捕获此异常(顺便说一下,这是一个
RuntimeExeption


如果您坚持使用穷人检查,请不要分配
id
,并检查在持久化之后是否仍有默认值(在您的情况下,它将是
0L
)。

在EclipseLink中,可以使用IdValidation枚举和@PrimaryKey注释或“EclipseLink.id validation”持久化单元属性配置此项

默认情况下,null和0将导致重新生成id,但将使用其他值。如果将IdValidation设置为负数,则负数也将被替换


您还可以将序列对象配置为始终替换该值。

在EclipseLink中,这可以使用IdValidation枚举和@PrimaryKey注释或“EclipseLink.id validation”持久化单元属性进行配置

默认情况下,null和0将导致重新生成id,但将使用其他值。如果将IdValidation设置为负数,则负数也将被替换


您还可以将Sequence对象配置为始终替换该值。

但我设置该值是为了检查它是否会被更改。我问是否有任何配置强制JPA提供程序用新生成的值覆盖该值?。或者有一个供应商真的这么做?!。或者是否有解决此问题的配置?当我使用eclipselink时,它在数据库中保留了-1,而没有用生成的值覆盖它,但当我使用hibernate时,它抛出了异常。这在JPA规范中没有定义,所以请期待任何结果。在这种情况下,一个实现可以做它感觉到的事情;指责规范没有指定行为。DataNucleus允许您设置值,在这种情况下不为字段生成值。非常感谢,但请您说“DataNucleus允许您设置值,在这种情况下不为字段生成值”。是否有其他提供商允许我设置值,然后在保留实体时生成新值不知道。我写DataNucleus,为什么我可能会推荐一个不同的呢?没有其他人具有同样的灵活性,但我不想要这种灵活性。我希望另一个覆盖我将由生成的值设置的值。因为我设置这个值是为了指示实体是否在数据库中持久化。如果您知道为什么hibernate提供程序在eclipselink作为DataNucleus工作时运行上述代码时抛出“org.hibernate.PersistentObjectException:Distached entity passed to persistent”,但我设置此值以检查是否会更改它。我问是否有任何配置强制JPA提供程序用新生成的值覆盖该值?。或者有一个供应商真的这么做?!。或者是否有解决此问题的配置?当我使用eclipselink时,它在数据库中保留了-1,而没有用生成的值覆盖它,但当我使用hibernate时,它抛出了异常。这在JPA规范中没有定义,所以请期待任何结果。在这种情况下,一个实现可以做它感觉到的事情;指责规范没有指定行为。DataNucleus允许您设置值,在这种情况下不为字段生成值。非常感谢,但请您说“DataNucleus允许您设置值,在这种情况下不为字段生成值”。是否有其他提供商允许我设置值,然后在保留实体时生成新值不知道。我写DataNucleus,为什么我可能会推荐一个不同的呢?没有其他人具有同样的灵活性,但我不想要这种灵活性。我希望另一个覆盖我将由生成的值设置的值。因为我设置这个值是为了指示实体是否在数据库中持久化。如果您知道为什么hibernate提供程序抛出“org.hibernate.PersistentObjectException:已传递分离实体”
public class Sear {
    public static void main(String[] args) throws Exception {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("testID");
        EntityManager em = emf.createEntityManager();
        Man man = new Man();
        man.setId(-1L);
        try {
            em.getTransaction().begin();
            em.persist(man);
            em.getTransaction().commit();
        } catch (Exception e) { }
            if(man.getId() == -1);  
        }
    }
}