2017-04-26 30 views
2

我试图从休眠添加一个新用户到火鸟数据库的表Hibernate不使用火鸟序列,但尝试使用,而不是

Session session = factory.openSession(); 

UserDetail user = new UserDetail(); 
user.setName("Mark"); 
user.setPassword("1234567"); 
user.setUserType(1L); 

session.beginTransaction(); 
try { 
    session.persist(user); 
    session.getTransaction().commit(); 
} catch (Exception e) { 
    session.getTransaction().rollback(); 
} finally { 
    session.close(); 
} 

和我的实体是

@Entity 
@Table(name = "USER_DETAIL") 
public class UserDetail 
{ 
    @Id 
    @Column(name = "ID", nullable = false) 
    @SequenceGenerator(name = "gen", sequenceName = "GEN_USER_DETAIL_ID") 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "gen") 
    private Long id; 

    @Column(name = "TYPE_ID") 
    @NotNull 
    private Long userType; 

    @Column(name = "NAME") 
    @NotNull 
    @Size(min = UserDetailConstraint.MIN_USER_NAME, max = UserDetailConstraint.MAX_USER_NAME) 
    private String name; 

    @Column(name = "HASHED_PASSWORD") 
    @NotNull 
    @Size(min = UserDetailConstraint.MIN_PASSWORD, max = UserDetailConstraint.MAX_PASSWORD) 
    private String password; 

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

    public Long getUserType() { return userType; } 
    public void setUserType(Long userType) { this.userType = userType; } 

    public String getName() { return name; } 
    public void setName(String name) { this.name = name; } 


    public String getPassword() { return password; } 
    public void setPassword(String password) { this.password = password; } 
} 

但是当Hibernate试图通过发电机来获取新的ID,它使用

select next_val as id_val from GEN_USER_DETAIL_ID with lock 

GEN_USER_DETAIL_ID为n一张桌子,它是一个序列。

所以程序有错误

WARN: HHH10001002: Using Hibernate built-in connection pool (not for 

production use!) 
апр 26, 2017 5:19:06 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator 
INFO: HHH10001005: using driver [org.firebirdsql.jdbc.FBDriver] at URL [jdbc:firebirdsql://localhost:3050/warehouse] 
апр 26, 2017 5:19:06 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator 
INFO: HHH10001001: Connection properties: {user=SYSDBA, password=****} 
апр 26, 2017 5:19:06 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator 
INFO: HHH10001003: Autocommit mode: false 
апр 26, 2017 5:19:06 PM org.hibernate.engine.jdbc.connections.internal.PooledConnections <init> 
INFO: HHH000115: Hibernate connection pool size: 5 (min=1) 
апр 26, 2017 5:19:06 PM org.hibernate.dialect.Dialect <init> 
INFO: HHH000400: Using dialect: org.hibernate.dialect.FirebirdDialect 
апр 26, 2017 5:19:06 PM org.hibernate.id.enhanced.SequenceStyleGenerator configure 
INFO: HHH000107: Forcing table use for sequence-style generator due to pooled optimizer selection where db does not support pooled sequences 
апр 26, 2017 5:19:07 PM org.hibernate.validator.internal.util.Version <clinit> 
INFO: HV000001: Hibernate Validator 4.3.2.Final 
Hibernate: select next_val as id_val from GEN_USER_DETAIL_ID with lock 
апр 26, 2017 5:19:07 PM org.hibernate.id.enhanced.TableStructure$1$1 execute 
ERROR: could not read a hi value 
org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544569. Dynamic SQL Error 
SQL error code = -204 
Table unknown 
GEN_USER_DETAIL_ID 
At line 1, column 51 

当我使用XML映射,而不是注释,然后一切工作正常崩溃。

我该如何解决这个问题?

+0

这是很重要的序列式发电机表使用强制由于汇集优化选择其中db不支持合并的序列,你的数据库是不支持Sequnce,你可以看看 – rajadilipkolli

+0

@rajadilipkolli火鸟支持序列,只是不是合并序列。 –

+0

如果您找到了解决方案,而不是解决方案,我建议您使用该解决方案发布自己的答案(并在超时后接受该答案)。 –

回答

1

@SequenceGenerator默认分配大小为50,这需要合并序列。 Firebird不支持混合序列(技术上它确实存在,但并不像Hibernate所要求的那样)。除1以外的分配大小会触发Hibernate使用基于表的策略。

这也表明在日志中:

апр26日,2017年下午5时19分06秒org.hibernate.id.enhanced.SequenceStyleGenerator配置
信息:HHH000107:强制表使用了序列 - 由于汇集优化选择,其中db不支持合并序列

由于您没有该表,因此会出现错误。

有几种解决方案:

  1. 更改分配大小为1

    @SequenceGenerator(name = "gen", 
         sequenceName = "GEN_USER_DETAIL_ID", 
         allocationSize = 1) 
    
  2. 创建必要的表,而不是与1行来填充它:

    drop sequence GEN_USER_DETAIL_ID; 
    commit; 
    create table GEN_USER_DETAIL_ID (
        next_val INTEGER NOT NULL 
    ); 
    commit; 
    insert into GEN_USER_DETAIL_ID (next_val) values (1); 
    commit; 
    
  3. 创建一个触发器来分配ID(或者,如果您使用的是Firebird 3,则可以使用劳工处亦声明列是GENERATED BY DEFAULT AS IDENTITY

    set term #; 
    create trigger user_detail_bi before insert on user_detail 
    as 
    begin 
        new.id = next value for GEN_USER_DETAIL_ID; 
    end# 
    set term ;# 
    commit; 
    

    ,改变@GeneratedValueIDENTITY

    @Id 
    @Column(name = "ID", nullable = false) 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 
    

选项2和3是可能获得更好的性能。

+0

不能使用hibernate插入返回?那么也许使用生成器是可能的,没有触发器 –

+0

@ Arioch'The是的,它可以使用'insert .. returns',与选项3:'strategy = GenerationType.IDENTITY'一起使用,但这需要一个触发器或一个Firebird 3 - 身份栏。 –

0

我找到了一种使用firebird生成器的方法。需要这个。

@Id 
    @Column(name = "ID") 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "gen") 
    @GenericGenerator(name = "gen", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", 
      parameters = {@org.hibernate.annotations.Parameter(name = "sequence_name", value = "GEN_USER_DETAIL_ID") 
      }) 
相关问题