所以我们的项目使用PostgreSQL数据库,我们使用JPA来操作数据库,我们在Netbeans 7.1.2中使用自动创建器从数据库中创建实体。
在小的变化之后,我们的主键值被描述为:
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Basic(optional = false)
@NotNull
@Column(name = "idwebuser", nullable = false)
private Integer idwebuser;
问题是现在的应用程序不灵活,因为当我们直接修改数据库(使用SQL或其他工具)而不是通过Java应用程序时-生成的值低于实际的数据库ID值-因此我们在创建新实体时出错。
有没有可能JPA可以让数据库自动生成ID,然后在创建过程后获得它?或者有什么更好的解决方案?谢谢。
编辑更具体:我们有一个用户表,我的问题是,使用任何类型的策略generationtype,JPA插入一个新的实体,由它的生成器ID指定。这对我来说是错误的,因为如果我自己对表进行更改,通过添加新条目,应用程序的GeneratedValue低于当前ID -这导致我们出现ID重复的异常。我们可以修复它吗?)?
- 关于答案的简短说明 * 我这边有一个小谎言,因为我们使用了PG管理-〉查看前100行并从那里编辑行,而不是使用select。事实证明,这个编辑器不知何故跳过了更新ID的过程,所以即使在DB中,当我们编写一个正确的INSERT时,它也会用不正确的ID执行!因此,这基本上是我们使用的编辑器的问题,而不是数据库和应用程序的问题。
现在它甚至可以使用@GeneratedValue(strategy=GenerationType.IDENTITY)
6条答案
按热度按时间flvtvl501#
给定表定义:
使用Map:
命名
tablename_columname_seq
是PostgreSQL默认的SERIAL
序列命名,我建议您坚持使用它。如果需要Hibernate与数据库的其他客户端协作,
allocationSize=1
很重要。请注意,如果事务回滚,这个序列中将有“间隙”。事务可以由于各种原因回滚。您的应用程序应该设计为科普此问题。
n
都有一个idn-1
或n+1
n
是在小于n
的id之前或大于n
的id之后添加或提交的。而是在表中记录时间戳。参见PostgreSQL documentation for sequences和串行数据类型。
他们解释说,上面的表定义基本上是一个快捷方式:
这应该有助于解释为什么我们添加了
@SequenceGenerator
注解来描述序列。如果你真的必须有一个无间隙的序列(例如支票或发票编号),请参阅gapless sequences,但认真地说,避免这种设计,并且 * 永远 * 不要将其用作主键。
注意:如果您的表定义是这样的:
然后使用(unsafe,do not use)插入:
或者(* safe,never do this*):
那么 * 你做错了 *,应该切换到一个序列(如上所示)或一个使用锁定计数器表的 * 正确的 * 无间隙序列实现(再次,请参阅上文并参阅Google中的“无间隙序列postgresql”)。如果数据库上有多个连接,则上述两种方法都会出错。
os8fio9y2#
看起来你必须像这样使用序列生成器:
hmae6n7t3#
请尝试使用
GenerationType.TABLE
而不是GenerationType.IDENTITY
。数据库将创建单独的表,用于生成唯一的主键,它还将存储最后使用的ID号。mf98qq944#
您也可以通过编写脚本来执行通用
GenerationType.IDENTITY
到所选答案提出的解决方案的大量转换,从而保存一些精力。下面的脚本对Java源文件的格式有一些轻微的依赖性,并且将在没有备份的情况下进行修改。运行脚本后:
1.搜索并将
import javax.persistence.Table;
替换为import javax.persistence.Table; import javax.persistence.SequenceGenerator;
。1.在NetBeans中重新格式化源代码,如下所示:
1.选择要格式化的所有源文件。
1.按Alt+Shift+F
1.确认重新格式化。
将以下脚本保存为
update-sequences.sh
或类似文件:使用NetBeans生成CRUD应用程序时,ID属性将不包括可编辑的输入字段。
y3bcpkx15#
对我有用
1.创建这样的表,使用SERIAL。
1.在id字段添加@GeneratedValue(strategy = GenerationType.IDENTITY)。
aydmsdu96#
解决方案
不工作。这是一个谎言。问题仍然存在。请在发布前审查!!