Сгенерированные первичные ключи начинаются с формы 9951 вместо 10000
-
17-09-2020 - |
Вопрос
Я использую:
NetBeans IDE 6.7.1, GlassFish v2.1, Oracle 10g XE, JAVA 6 SE, JAVA 5 EE,
Изнутри EJB без сохранения состояния я сохраняю сущности типа customer, у меня есть аннотация:@SequenceGenerator(name="seq", sequenceName="cust_id_seq") в классе customer, поэтому первичные ключи автоматически генерируются в базе данных из последовательности cust_id_seq, но когда я сохраняю первого клиента, первичный ключ равен 9951 вместо 10000, первичный ключ второго клиента равен 9952.Результат работы GlassFish v2.1 после того, как я сохранил двух клиентов, таков:
Запуск сервера приложений завершен.
Мое удостоверение личности - это:0
Верхняя ссылка, версия:Oracle TopLink Essentials - 2.1 (сборка b31g-fcs (19.10.2009))
Сервер:неизвестно file:/C:/Documents%20and%20Settings/IOANNIS_PAPAIOANNOU/My%20Documents/NetBeansProjects/VideoClub/dist/gfdeploy/VideoClub-ejb_jar/- вход в систему vc_pu завершен успешно
Мое удостоверение личности - это:9951
Мое удостоверение личности - это:0
Мое удостоверение личности - это: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
/
Яннис П.
Решение 2
В объекте клиента в аннотации @ ToxenceGenerator я добавил атрибут аллецизироваться со значением 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;
...
}
. Другие советы
Я думаю, тебе следует измениться CREATE SEQUENCE cust_id_seq ... INCREMENT BY
1
к ... INCREMENT BY
50
.И вот почему.
Объявленное приращение последовательности должно соответствовать @SequenceGenerator
'с allocationSize
параметр. allocationSize
не указано и, следовательно, по умолчанию равно 50.Но истинный INCREMENT BY
это всего лишь 1, а не 50.Таким образом, существует несоответствие между allocationSize
и настоящий INCREMENT BY
.
Вот как это несоответствие может вызвать проблему.Вызовы TopLink Essentials (TLE) NEXTVAL()
на cust_id_seq
.Последовательность возвращает 10000 + 1.TLE предполагает, что последовательность просто увеличена на 50 (JPA по умолчанию allocationSize
) вместо 1 (фактическая сумма).TLE вычитает allocationSize
= 50 от 10001, чтобы получить 9951.
Кстати, если у вас есть такая возможность, подумайте о переходе на преемника TLE, Ссылка на затмение (и к Стеклянная рыба v3).