Ata*_*ais 36 postgresql entity netbeans jpa java-ee
所以我们的项目使用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,然后在创建过程后获取它?或者什么是更好的解决方案?谢谢.
编辑 更具体地说:我们有一个用户表,我的问题是使用任何类型的策略生成类型,JPA正在插入一个具有由其生成器ID指定的新实体.这对我来说是错误的,因为如果我自己对表进行更改,通过添加新条目,应用程序的GeneratedValue低于当前ID - 这导致我们出现重复ID异常.我们能解决它吗?)?
关于答案的简短说明 我身边有一个小谎言,因为我们使用了PG管理员 - >查看前100行并从那里编辑了行而不是使用选择.但是,事实证明,这个编辑器以某种方式跳过了更新ID的过程,因此即使在DB中,当我们编写一个正确的INSERT时,它也会被执行不正确的ID!所以它基本上是我们使用的编辑器的问题,而不是数据库和应用程序......
现在它甚至可以使用 @GeneratedValue(strategy=GenerationType.IDENTITY)
Cra*_*ger 72
鉴于表定义:
CREATE TABLE webuser(
    idwebuser SERIAL PRIMARY KEY,
    ...
)
使用映射:
@Entity
@Table(name="webuser")
class Webuser {
    @Id
    @SequenceGenerator(name="webuser_idwebuser_seq",
                       sequenceName="webuser_idwebuser_seq",
                       allocationSize=1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
                    generator="webuser_idwebuser_seq")
    @Column(name = "idwebuser", updatable=false)
    private Integer id;
    // ....
}
命名tablename_columname_seq是PostgreSQL默认序列命名SERIAL,我建议你坚持下去.
allocationSize=1如果您需要Hibernate与其他客户端合作到数据库,这一点很重要.
请注意,如果事务回滚,此序列中将包含"间隙".由于各种原因,事务可以回滚.您的应用程序应该设计为应对此问题.
n有身份证n-1或身份证n+1n在id大于n或小于id之前添加或提交n.如果你对如何使用序列非常小心,你可以这样做,但你永远不应该尝试; 记录表中的时间戳.有关序列和串行数据类型,请参阅PostgreSQL文档.
他们解释说上面的表定义基本上是一个快捷方式:
CREATE SEQUENCE idwebuser_id_seq;
CREATE TABLE webuser(
    idwebuser integer primary key default nextval('idwebuser_id_seq'),
    ...
)
ALTER SEQUENCE idwebuser_id_seq OWNED BY webuser.idwebuser;
...这应该有助于解释为什么我们添加了一个@SequenceGenerator注释来描述序列.
如果你真的必须有一个无间隙序列(例如,检查或发票编号),请参见无间隙序列,但严重的是,避免这种设计,并且永远不要将它用作主键.
注意:如果您的表定义如下所示:
CREATE TABLE webuser(
    idwebuser integer primary key,
    ...
)
并且你使用(不安全,不要使用)插入它:
INSERT INTO webuser(idwebuser, ...) VALUES ( 
    (SELECT max(idwebuser) FROM webuser)+1, ...
);
或(不安全,永远不要这样做):
INSERT INTO webuser(idwebuser, ...) VALUES ( 
    (SELECT count(idwebuser) FROM webuser), ...
);
然后你做错了,应该切换到序列(如上所示)或使用锁定的计数器表进行正确的无间隙序列实现(再次参见上文并参见Google中的"无间隙序列postgresql").如果数据库上有多个连接,则上述操作都是错误的.
| 归档时间: | 
 | 
| 查看次数: | 51471 次 | 
| 最近记录: |