Pregunta

Hago uso de:

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

Desde dentro de un EJB sin estado persisto entidades de tipo cliente. Tengo la anotación:@SequenceGenerator (name = "seq", secuenceName = "cust_id_seq") en el cliente de la clase, por lo que las claves principales se autenógenas en la base de datos desde la secuencia cust_id_seq pero cuando persiste el primer cliente, la clave principal es 9951 en lugar de 10000, la primaria, la primaria La clave del segundo cliente es 9952.El resultado de GlassFish v2.1 después de persistir con dos clientes es:

Inicio del servidor de aplicaciones completo.

Mi identificacion es:0

TopLink, versión:Oracle TopLink Essentials - 2.1 (compilación b31g-fcs (19/10/2009))

Servidor:Archivo desconocido:/c:/documentos%20and%20settings/ioannis_papaioannou/my%20documents/netbeansprojects/videoclub/dist/gfdeploy/videoclub -ejb_jar/-vc_pu exitoso

Mi identificacion es:9951

Mi identificacion es:0

Mi identificacion es: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;
}


}

el código del 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 del script que crea la base de datos:

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.

¿Fue útil?

Solución 2

En la entidad del cliente en la anotación @SequenceGenerator, agregué la asignación de atributos con el valor 1, ahora las claves principales comienzan desde 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;  
...
}

Otros consejos

creo que deberías cambiar CREATE SEQUENCE cust_id_seq ... INCREMENT BY1 a ... INCREMENT BY50.He aquí por qué.

El incremento de secuencia declarado debe coincidir con el @SequenceGenerator's allocationSize parámetro. allocationSize no se especifica y, por lo tanto, el valor predeterminado es 50.pero la verdad INCREMENT BY es solo 1, no 50.Entonces hay un desajuste entre allocationSize y lo real INCREMENT BY.

Así es como esta falta de coincidencia podría causar el problema.Llamadas TopLink Essentials (TLE) NEXTVAL() en cust_id_seq.La secuencia devuelve 10000 + 1.TLE asume la secuencia recién incrementada en 50 (JPA predeterminado allocationSize) en lugar de 1 (importe real).TLE resta allocationSize = 50 de 10001 para obtener 9951.

Por cierto, si tiene la libertad de hacerlo, considere actualizar al sucesor de TLE, EclipseEnlace (y para Pez de cristal v3).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top