2010-07-19 11 views
1

我利用:生成主鍵啓動形式9951,而不是10000

的NetBeans IDE 6.7.1, GlassFish的V2.1, 的Oracle 10g XE, JAVA 6 SE, JAVA EE 5,

從一個無狀態EJB我堅持類型的客戶的實體內我有註釋: @SequenceGenerator(NAME =「序列」,sequenceName =「cust_id_seq」)在類的客戶,以便在 主鍵從數據庫中自動生成序列cust_id_seq,但是當我堅持第一個客戶時,主鍵是9951而不是1000 0,第二個客戶的主鍵是9952.在我堅持兩個客戶之後,GlassFish v2.1的輸出是:

應用程序服務器啓動完成。

我的ID是:0

TopLink的版本:將Oracle TopLink Essentials - 2.1(建設B31G-FCS(2009/10/19))

服務器:未知 文件:/ C:/文件%20於是%20Settings/IOANNIS_PAPAIOANNOU /我的%20Documents /的NetBeansProjects/VideoClub /距離/ gfdeploy/VideoClub-ejb_jar/-vc_pu登陸成功,

我的ID是:9951

我的ID是:0

我的ID是:9952

@Entity 
@Table(name = "customer") 
@SequenceGenerator(name="seq", sequenceName="cust_id_seq") 
public class Customer implements Serializable 
{ 

@Id 
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq") 
@Column(name="CUST_ID") 
private int id; 

@Column(name = "phone_number") 
private int phoneNumber; 

@Column(name = "first_name") 
private String firstName; 

@Column(name = "last_name") 
private String lastName; 

@Column(name = "credit") 
private int credit; 

@OneToMany  
private Collection<CustRentMovie> rents = new ArrayList<CustRentMovie>(); 

public int getCredit() 
{ 
    return credit; 
} 

public void setCredit(int credit) 
{ 
    this.credit = credit; 
} 

public String getFirstName() 
{ 
    return firstName; 
} 

public void setFirstName(String firstName) 
{ 
    this.firstName = firstName; 
} 

public int getId() 
{ 
    return id; 
} 

public void setId(int id) 
{ 
    this.id = id; 
} 

public String getLastName() 
{ 
    return lastName; 
} 

public void setLastName(String lastName) 
{ 
    this.lastName = lastName; 
} 

public int getPhoneNumber() 
{ 
    return phoneNumber; 
} 

public void setPhoneNumber(int phoneNumber) 
{ 
    this.phoneNumber = phoneNumber; 
} 

public Collection<CustRentMovie> getRents() 
{ 
    return rents; 
} 

public void setRents(Collection<CustRentMovie> rents) 
{ 
    this.rents = rents; 
} 


} 

的EJB的代碼:腳本

@Stateless 
public class ClerkSessionBean implements ClerkSessionRemote 
{ 

@PersistenceContext(unitName = "vc_pu") 
private EntityManager em; 

public int writeCustomer(AlmostCustomer almostCustomer) 
{ 

    Customer customer = new Customer(); 
    System.out.println("My id is: " + customer.getId()); 
    customer.setFirstName(almostCustomer.getFirstName()); 
    customer.setLastName(almostCustomer.getLastName()); 
    customer.setPhoneNumber(almostCustomer.getPhoneNumber()); 
    em.persist(customer); 
    System.out.println("My id is: " + customer.getId()); 
    return customer.getId(); 
} 
} 

部分用於創建數據庫:

CREATE table customer 
(
cust_id NUMBER(5), 
phone_number NUMBER(10) NOT NULL, 
first_name VARCHAR2(12) NOT NULL, 
last_name VARCHAR2(30) NOT NULL, 
-- Τα χρήματα που έχει ένας πελάτης στο λογαριασμό του. 
credit NUMBER(5, 2) DEFAULT 0 NOT NULL, 
CONSTRAINT cust_pk PRIMARY KEY (cust_id), 
-- Μόνο ένας λογαριασμός για κάθε σπίτι. 
CONSTRAINT phone_unique UNIQUE (phone_number) 
) 
/

DROP SEQUENCE cust_id_seq 
/

CREATE SEQUENCE cust_id_seq MINVALUE 10000 MAXVALUE 99999 INCREMENT BY 1 START WITH 10000 NOCACHE NOCYCLE ORDER 

/

雅尼斯P 。

回答

0

在註釋@SequenceGenerator客戶實體我加了屬性附加傷害allocationSize值爲1,現在的主鍵從10000

@Entity 
@Table(name = "customer") 
@SequenceGenerator(name="seq", sequenceName="cust_id_seq", allocationSize=1) 
public class Customer implements Serializable 
{ 

    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq") 
    @Column(name="CUST_ID") 
    private int id; 
... 
} 
3

我認爲你應該改變CREATE SEQUENCE cust_id_seq ... INCREMENT BY1... INCREMENT BY50。這是爲什麼。

聲明的序列增量應該與@SequenceGeneratorallocationSize參數匹配。 allocationSize未指定,因此默認爲50.但真正的INCREMENT BY只有1,而不是50.因此,allocationSize與真實INCREMENT BY之間存在不匹配。

下面是這種不匹配如何導致問題。 TopLink Essentials(TLE)在cust_id_seq上調用NEXTVAL()。該序列返回10000 + 1.TLE假定序列剛剛增加50(默認JPA allocationSize)而不是1(實際量)。 TLE從10001減去allocationSize = 50得到9951.

順便說一下,如果您有這樣的自由,請考慮升級到TLE的後繼者EclipseLink(和Glassfish v3)。

+0

+1開始你在整條生產線是正確的。 1)是的,序列生成器的'allocationSize'必須與數據庫中序列的增量值匹配。 2)是的,這就是算法在TLE方面的工作原理。 3)是的,JPA 1.0的默認'allocationSize'也是50。 – 2010-07-21 01:59:48

+0

@帕斯卡爾Thivent - 感謝您的專業知識! – 2010-07-21 02:09:19

+0

我現在正在度假,下週我會試試你的解決方案。 – IVANNHS 2010-07-21 06:10:04