Pergunta

Eu faço uso de:

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

De dentro de um EJB sem estado eu persisto entidades do tipo cliente tenho a anotação:@SequenceGenerator (name = "seq", sequencename = "cust_id_seq") no cliente da classe para que as chaves primárias sejam autogeneradas no banco de dados da sequência cust_id_seq, mas quando persisto o primeiro cliente, a chave primária é 9951 em vez de 10000, o primário A chave do segundo cliente é 9952.A saída do GlassFish v2.1 depois de persistir dois clientes é:

Inicialização do servidor de aplicativos concluída.

Minha identificação é:0

TopLink, versão:Oracle TopLink Essentials - 2.1 (Build b31g-fcs (19/10/2009))

Servidor:Arquivo desconhecido:/c:/documentos%20e%20settings/ioannis_papaioannou/my%20documents/netbeansprojects/videoclub/dist/gfdeploy/videoclub-ejb_jar/-vc_pu Login bem-sucedido

Minha identificação é:9951

Minha identificação é:0

Minha identificação é: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;
}


}

o código do 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 do script que cria o banco de dados:

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.

Foi útil?

Solução 2

Na entidade cliente na anotação @SequenceGenerator adicionei o atributo alocaçãoSize com valor 1, agora as chaves primárias iniciam em 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;  
...
}

Outras dicas

Eu acho que você deveria mudar CREATE SEQUENCE cust_id_seq ... INCREMENT BY1 para ... INCREMENT BY50.Aqui está o porquê.

O incremento de sequência declarado deve corresponder ao @SequenceGeneratorde allocationSize parâmetro. allocationSize não é especificado e, portanto, o padrão é 50.Mas a verdade INCREMENT BY é apenas 1, não 50.Portanto, há uma incompatibilidade entre allocationSize e o verdadeiro INCREMENT BY.

Veja como essa incompatibilidade pode causar o problema.Chamadas TopLink Essentials (TLE) NEXTVAL() sobre cust_id_seq.A sequência retorna 10.000 + 1.TLE assume a sequência apenas incrementada em 50 (padrão JPA allocationSize) em vez de 1 (valor real).Subtrações TLE allocationSize = 50 de 10.001 para obter 9.951.

A propósito, se você tiver liberdade para fazer isso, considere atualizar para o sucessor do TLE, Eclipse Link (e para Peixe-vidro v3).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top