Jpa 每次执行服务器和客户端时,Id的GeneratedValue计数器都会重置

Jpa 每次执行服务器和客户端时,Id的GeneratedValue计数器都会重置,jpa,eclipselink,primary-key,generated,Jpa,Eclipselink,Primary Key,Generated,我正在使用EJB和JPA开发一个JavaEE应用程序 例如,我的实体定义如下: @Entity public class Utente implements Serializable { @Id @GeneratedValue private int cod_utente; private String nome_utente; private String morada_utente; @Temporal(TemporalType.DATE) private GregorianCalenda

我正在使用EJB和JPA开发一个JavaEE应用程序

例如,我的实体定义如下:

@Entity
public class Utente implements Serializable {

@Id
@GeneratedValue
private int cod_utente;
private String nome_utente;
private String morada_utente;
@Temporal(TemporalType.DATE)
private GregorianCalendar dnasc_utente;
private int tel_utente;
private List<GregorianCalendar> agenda;
@OneToMany
@JoinColumn(nullable=true)
private List<Prescricao> lista_presc;
@实体
公共类Utene实现了可序列化{
@身份证
@生成值
私家侦探;
私人字符串名称;
私人字符串morada_utente;
@时态(TemporalType.DATE)
格雷戈里安·卡伦达·德纳塞特私人酒店;
私人国际电话;
私人名单议程;
@独身癖
@JoinColumn(nullable=true)
私人名单;
当我创建实体Utene时,会从一个开始依次生成密钥。如果我关闭客户端和服务器并再次执行它们,则会重新建立密钥生成器的“计数器”。这会导致错误,因为应用程序将尝试创建另一个主键为“1”的Utene

有人能帮我解决这个问题吗?

代码:

@Id
@GeneratedValue
private int cod_utente;
不设置特定的策略来生成ID的值

与此代码相同:

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int cod_utente;
意味着持久性提供程序(在Glassfish中,默认持久性提供程序为EclipseLink)应为您使用的数据库选择适当的策略。在您的情况下,持久性提供程序似乎正在选择一种策略,即在服务器重新启动后重新启动值

有不同的生成策略,您可以在中找到一些详细信息

我想您最好使用数据库序列(
GenerationType.sequence
)来生成ID值

例如:

创建一个名为
GEN_sequence
的数据库序列(如果您让持久性提供程序生成表,我想您也可以让它以某种方式创建序列,但本例将演示如何手动创建),您应该在正在使用的数据库中查找有关如何执行此操作的信息(可能类似于
创建序列genu SEQUENCE;
)。将代码更改为:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_seq_gen")
@SequenceGenerator(name = "my_seq_gen", sequenceName = "GEN_SEQUENCE")
private int cod_utente;
您也可以对不同的类使用相同的序列

更新:

对于可以设置分配大小的,此值是保留的序列值量。默认值为50。当序列从0开始时,第一次从序列请求值时,序列分配(并保留)值0-49(或1-50)。这些值可由持久性提供程序使用,直到所有值都已使用,然后接下来的50个值(50-99或51-100)将被分配和保留。序列会记住当前位置,以便在多个类使用时不会两次给出相同的范围

对于allocationSize的值,您可以保留默认值,但这可能会在ID中产生间隙。如果分配(保留)一个序列范围(如0-49),并且仅使用一个或部分值(如0、1和2),则此范围(3-49)的其他值将“丢失”服务器重新启动时。下一次分配的值范围将为50-99,因此表中的下一个ID将为50。
现在,您的表中有以下ID:
0,1,2,50
。通常这不会有问题,但您也可以将allocationSize设置为较低的值或1,以避免产生此类间隙

另请参见:


AFAIK应该可以。您是否尝试过手动设置不同的生成策略?顺便问一下,哪个JPA提供商?哪个DB系统?JPA属性设置为那种方言?我使用的是glassfish。JPA提供商是EclipseLink要使用该策略,我们需要设置
allocationSize
正确吗?该值对应什么?标准是什么我在我的实体中写了这段代码:
@Id@SequenceGenerator(name=“seq7”,initialValue=1,allocationSize=100)@GeneratedValue(strategy=GenerationType.SEQUENCE,generator=“seq7”)private int cod_ficha;
但是在运行服务器时发生了这个错误:
异常[EclipseLink-4002](Eclipse持久性服务-2.5.2.v20140319-9ad6abd):org.Eclipse.Persistence.exceptions.DatabaseException内部异常:java.sql.SQLSyntaxErrorException:序列“SEQ7”不存在。错误代码:30000调用:值(SEQ7的下一个值)查询:ValueReadQuery(sql=“VALUES(SEQ7的下一个值)”)
错误消息显示,序列不存在。如回答中所述,您必须在数据库中手动创建序列。