2017-04-26 58 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") 
      }) 
相關問題