Domanda

Io uso di:

Netbeans IDE 6.7.1, Glassfish V2.1, Oracle 10G XE, Java 6 SE, Java 5 EE,

Dall'interno di un EJB apolide, persistono entità di tipo cliente ho l'annotazione: @SerzeGenerator (nome="seq", sequencename="cust_id_seq") nel cliente di classe così il Le chiavi primarie sono autentate nel database dalla sequenza cust_id_seq ma quando persistono il primo cliente, la chiave primaria è 9951 anziché 10000, la chiave primaria del secondo cliente è 9952. L'uscita del Glassfish V2.1 dopo aver perse intenzione di due clienti è:

Avvio del server dell'applicazione Completa.

Il mio ID è: 0

TopLink, Versione: Oracle Toplink Essentials - 2.1 (Build B31G-FCS (10/19/2009))

Server: sconosciuto File: / C: / Documenti% 20and% 20Settings / Ioannis_papaioannou / My% 20Documenti / NetBeansProjects / Videoclub / dist / GFDeploy / Videoclub-EJB_JAR / -VC_PU Accesso Giusto

Il mio ID è: 9951

Il mio ID è: 0

Il mio 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;
}


}
.

Il codice dell'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();
}
}
.

Parte dello script che crea il database:

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
.

/

yiannis p.

È stato utile?

Soluzione 2

Nell'entità del cliente nell'annotazione @SequenceGenerator ho aggiunto l'allocazione Atribute con il valore 1, ora i tasti primari iniziano da 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;  
...
}
.

Altri suggerimenti

Penso che dovresti cambiare CREATE SEQUENCE cust_id_seq ... INCREMENT BY 1 a ... INCREMENT BY 50 . Ecco perché.

L'incremento della sequenza dichiarata dovrebbe corrispondere al parametro @SequenceGeneratortaGcode del allocationSize. allocationSize non è specificato e quindi predefinito a 50. Ma il vero INCREMENT BY è solo 1, non 50. Quindi c'è una mancata corrispondenza tra allocationSize e il INCREMENT BY reale.

Ecco come questa mancata corrispondenza potrebbe causare il problema. TopLink Essentials (TLE) chiama NEXTVAL() su cust_id_seq. La sequenza ritorna 10000 + 1. TLE assume la sequenza appena incrementata da 50 (allocationSize JPA predefinito) anziché 1 (importo effettivo). Sottrae tle allocationSize= 50 da 10001 per ottenere 9951.

A proposito, se hai la libertà di farlo, considera l'aggiornamento al successore di Tle, eclipselink (e Glassfish V3 ).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top