2014-04-01 75 views
0

對於我的桌面應用程序,我使用JavaFX,Spring,JPA + Hibernate和PostgreSQL。目前我遇到過幾個問題。差距在JPA @GeneratedValue中使用PostgreSQL生成的序列值

問題一個:PRIMARY KEY約束SQL錯誤

違反當我按下面的方式(如GenerationType AUTO),它工作正常創建實體類。但是,當我創建一個新的數據庫,並添加一些測試數據與SQL腳本(如下圖所示),並嘗試插入一些數據與我的應用程序,我已經'違反PRIMARY KEY約束'SQL錯誤。這意味着看起來Hibernate嘗試生成已經可用的PK值(用我的測試數據ex 1,2,3等分配)。但經過5次嘗試(超過測試數據最大pK值)它是細,並用6

實體類開始將數據與PK密鑰值插入 - GenerationType爲AUTO

@Entity 
@Table(name = "devicetype") 
public class Devicetype implements Serializable { 

    @Id 
    @Basic(optional = false) 
    @Column(name = "id") 
    private Integer id; 

} 

表與初始測試數據

Table with initial test data

EntityManager的工廠

<bean id="entityManagerFactory" 
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" /> 
    <property name="packagesToScan" value="com.core.domain" /> 
    <property name="jpaProperties"> 
     <props> 
      <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop> 
      <prop key="hibernate.dialect">org.hibernate.dialect.PostgresPlusDialect</prop> 
      <prop key="hibernate.hbm2ddl.auto">update</prop> 
      <prop key="hibernate.show_sql">false</prop> 
      <prop key="hibernate.format_sql">false</prop> 
      <prop key="hibernate.use_sql_comments">false</prop> 
      <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop> 
     </props> 
    </property> 
</bean> 

問題二:空白序列值

約誤差對於化妝決心我已經根據以下方式改變實體類(GenerationType如SEQUENCE)和進行相同的步驟(插入初始用sql腳本測試數據並嘗試通過應用程序插入數據)。然後插入數據沒有任何例外。現在我的表格包含通過腳本和應用程序插入的記錄(如下圖所示)。但通過應用程序新添加數據(我突出顯示淺藍色)具有非常高的PK值(從184開始不是從6開始)。這意味着「GenerationType as SEQUENCE」似乎hibernate沒有按照順序方式填充ID值(保持一些間隙)。當我通過應用程序進一步添加一些數據時,似乎它會插入具有更高ID值的數據(不是開始形式214)。這意味着似乎ID不會按順序方式遞增。

實體類 - GenerationType如SEQUENCE具有間隙

@Entity 
@Table(name = "device_type") 
public class DeviceType implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE) 
    @SequenceGenerator(name="my_seq", sequenceName="MY_SEQ", allocationSize=1, initialValue=1) 
    @Basic(optional = false) 
    @Column(name = "ID") 
    private Integer id; 
} 

表數據(序列ID) enter image description here

+1

考慮另外兩個... –

+0

[在SQL表的主鍵ID之間的差距]的可能的複製(HTTP分裂問題:/ /stackoverflow.com/questions/39099905/gaps-between-primary-key-id-in-sql-table) – e4c5

回答

2

這是如何序列(和因此的PostgreSQL SERIAL型)的行爲。

如果您手動插入值,那麼您將需要update the sequence accordingly。或者更通常的是,不要手動插入值並讓序列完成。

除非您想鎖定每個插入表上的數據並消除任何併發的希望,否則空隙是不可避免的。我建議不要關心。

記住 - 數字並不代表什麼,它們只是一個方便的標識符。

花幾分鐘就這一切是如何工作的讀了起來:CREATE SEQUENCEALTER SEQUENCE

+0

此外,默認情況下,Hibernate以塊爲單位分配序列值,作爲插入性能的優化。您可以修改'@ SequenceGenerator'聲明來覆蓋它。 –

+0

@CraigRinger感謝您的評論。是的,我已經做了與分配大小= 1 – Channa

+0

@理查德謝謝feeb回來。當然我會參考這些資源。我注意到,即使我們沒有手動輸入任何數據,它會開始插入數據開始ID值與一些haddock值(不是從1開始,像這樣10) – Channa