Java 如何使用JPA GenerationType.AUTO提供初始值或增量ID

Java 如何使用JPA GenerationType.AUTO提供初始值或增量ID,java,hibernate,jpa,post,spring-data-jpa,Java,Hibernate,Jpa,Post,Spring Data Jpa,我使用以下代码定义MyEntity @Entity @Table(name = "MY_TABLE") public class MyEntity { @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name = "MY_TABLE_ID") private Integer myTableId; @Column(name = "MY_TABLE_NM") private String myTableName; //Gett

我使用以下代码定义MyEntity

@Entity
@Table(name = "MY_TABLE")
public class MyEntity {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "MY_TABLE_ID")
private Integer myTableId;

@Column(name = "MY_TABLE_NM")
private String myTableName;

//Getters Setters
}
对于应用程序启动后的第一次
POST
,我创建
MyEntity
一切正常,
myu TABLE\u ID
以1开始,并按预期工作

我的问题是,如果有人在我执行
POST
之前手动插入数据,那么我会得到重复的密钥异常,因为
myTableId
被输入为1,它已经存在

我的主要问题是我无法创建
数据库序列
,以便使用
GenerationType.sequence
立即解决此问题,因为现在无法更改数据库。 我已经尝试了
GenerationType
TableGenerator
的各种组合,但我无法成功解决它

initialValue
设置为更大的数字以避免重复值可以暂时解决我的问题,但我也无法这样做


如果有人能用
initialValue
AUTO
来帮助我,或者给我一些其他更好的解决方案,而不改变数据库,那就太好了:)

我使用生成类型标识,这基本上意味着db负责Id的生成

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@MappedSuperclass
@EntityListeners(EntityListener.class)
@EqualsAndHashCode(of = {"id", "createdAt"})
public abstract  class AbstractEntity<ID extends Serializable> implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private ID id;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "CREATED_AT", updatable = false)
    private Date createdAt;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "UPDATED_AT")
    private Date updatedAt;

}

如果需要更多的控制,还可以实现自己的生成器。 请参见此界面。 因此,您可以获得记录的计数,例如通过。 然后您可以自己生成一个标识符

public class MyEntityKeyGenerator implements IdentifierGenerator {
@Override
public Serializable generate(SessionImplementor session, Object object) {
    // SELECT count(ent) from MyEntity ent;
    Long count = (Long) session.getNamedQuery("count-query").uniqueResult();
    // calc and return id value
   }
}
实体:

class MyEntity {
@Id
@GenericGenerator(name = "my_generator",
        strategy = "org.common.MyEntityKeyGenerator")
@GeneratedValue(generator = "my_generator")
private Long id;...

请不要忘记锁。

因为
我的表ID
是一个标识列,下面的注释可以使用

@Entity
@Table(name = "MY_TABLE")
public class MyEntity {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY) // <-- IDENTITY instead of AUTO
@Column(name = "MY_TABLE_ID")
private Integer myTableId;

@Column(name = "MY_TABLE_NM")
private String myTableName;

//Getters Setters
}
@实体
@表(name=“MY_表”)
公共类MyEntity{
@身份证

@GeneratedValue(strategy=GenerationType.IDENTITY)/我在这里提供的答案中尝试了各种选项,在stackoverflow和其他论坛上也尝试了类似的问题

我没有什么限制

  • 我无法创建数据库序列,因为我的数据库更改已冻结
  • 我不想引入新的
    Custom
    IdGenerator类,因为它会给其他与我一起工作的人带来混乱
  • 通过以下更改解决了此问题:

    使用
    increment
    策略添加
    GenericGenerator
    ,对我有所帮助,我对代码做了以下更改

    @Entity
    @Table(name = "MY_TABLE")
    public class MyEntity {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator="seq")
    @GenericGenerator(name = "seq", strategy="increment")
    @Column(name = "MY_TABLE_ID")
    private Integer myTableId;
    
    @Column(name = "MY_TABLE_NM")
    private String myTableName;
    
    //Getters Setters
    }
    
    它帮助了我,因为, 从

    增量

    一种标识符生成器,返回通过计数构造的长字符串 从启动时的最大主键值开始。在 集群


    因为,即使手动插入,它也会增加现有的
    myTableId
    ,这解决了我的问题。

    表是如何设置的?mytable\u ID
    是一个标识列吗?是的,
    mytable\u ID
    是一个标识列。如果表已经有
    mytable\u ID
    =1,则code仍在尝试为fir插入1st请求并引发异常。对于第二个请求,代码插入2,但我不希望出现任何异常。然后,您的代码出现问题。这些注释是正确的注释。根据这些答案,我认为问题在于JPA/ORM。虽然我不确定。但是,我使用的是JpaRepository.save()插入records.JPA不是问题,hibernate也是问题。没有更多的代码,我不能告诉你更多。我在几乎每个项目中都使用hibernate和
    GenerationType.IDENTITY
    ,我从来没有遇到过这样的问题,主键列
    MY_TABLE\u ID
    它试图插入NULL,需要database change as per我尝试了上述两种方法,但无法使其运行,仍然面临相同的问题@MehdiWhich db you usingI am using postgresql我认为您应该在postgres中检查解决方案本身,但是,如果您使用大的分配大小,或者可能使用UUID生成ID,则GenerationType序列将起作用包。我不想创建自定义生成器,但是带有
    increment
    策略的GenericGenerator似乎正在工作,但我需要彻底测试它。谢谢,这正是我想要的。
    @Entity
    @Table(name = "MY_TABLE")
    public class MyEntity {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator="seq")
    @GenericGenerator(name = "seq", strategy="increment")
    @Column(name = "MY_TABLE_ID")
    private Integer myTableId;
    
    @Column(name = "MY_TABLE_NM")
    private String myTableName;
    
    //Getters Setters
    }