问题
I have a table in my SQL Server database where the primary key field is defined with NEWID()
as the default value. The expectation is client need not pass the primary key field value and the SQL server will handle it.
While defining my model class at JPA I have to define this ID field with a generation type. I tried IDENTITY
, TABLE
and SEQUENCE
Generator. Unfortunately I am getting an error as
Exception Description: Error preallocating sequence numbers.
The sequence table information is not complete..
My Persistence. XML is as below
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="LOB_Webservice" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.xyz.lob.model.jpa.OrderDetail</class>
<class>com.xyz.lob.model.jpa.OrderHeader</class>
<shared-cache-mode>NONE</shared-cache-mode>
<properties>
<property name="jboss.as.jpa.providerModule" value="org.eclipse.persistence"/>
<property name="javax.persistence.jdbc.driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:sqlserver://localhost:1433;databaseName=LOB_INT" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="*******" />
<property name="eclipselink.logging.level" value="FINE"/>
<property name="eclipselink.sharedCache.mode" value="None"/>
<property name="eclipselink.jdbc.cache-statements" value="false" />
<property name="eclipselink.query-results-cache" value="false"/>
<property name="eclipselink.logging.exceptions" value="true"/>
<property name="eclipselink.weaving" value="static"/>
</properties>
</persistence-unit>
My Model class is as below
@Entity
public class OrderHeader implements Serializable {
@Id
@Basic(optional = false)
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="OrderId")
private String orderId;
...
}
回答1:
Hi @Joe2013 Not sure if is still an issue but when using Table Generators AND you did not specified for Eclipse Link to generate the schema based on your object model, you must manually create the table AND also insert the rows for the corresponding generators and their initial values. Otherwise it will not work and you will get the error you mentioned.
回答2:
I have provided custom and default Sequence ID Generator examples as below.
Use Custom Sequence ID Generator (EclipseLink only)
Define Custom Sequence class
package org.phstudy.sequence;
public class MyNewIDSequence extends Sequence implements SessionCustomizer {
private static final long serialVersionUID = -6308907478094680131L;
public MyNewIDSequence() {
super();
}
public MyNewIDSequence(String name) {
super(name);
}
public void customize(Session session) throws Exception {
MyNewIDSequence sequence = new MyNewIDSequence("mynewid");
session.getLogin().addSequence(sequence);
}
@Override
public Object getGeneratedValue(Accessor accessor, AbstractSession writeSession, String seqName) {
DataReadQuery query = new DataReadQuery("select NEWID()");
query.setResultType(DataReadQuery.VALUE);
return writeSession.executeQuery(query);
}
@Override
public Vector getGeneratedVector(Accessor accessor, AbstractSession writeSession, String seqName, int size) {
return null;
}
@Override
public void onConnect() { }
@Override
public void onDisconnect() { }
@Override
public boolean shouldAcquireValueAfterInsert() {
return false;
}
@Override
public boolean shouldUsePreallocation() {
return false;
}
@Override
public boolean shouldUseTransaction() {
return false;
}
}
Register custom sequence in persistence.xml
<persistence ...>
<persistence-unit ...>
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<properties>
...
<property name="eclipselink.session.customizer" value="org.phstudy.sequence.MyNewIDSequence"/>
...
</persistence-unit>
</persistence>
Add Sequence Annotation with custom sequence name
@Entity
public class CustomSequence {
@Id
@GeneratedValue(generator = "mynewid")
private String id;
...
}
Use Default Sequence ID Generator (JPA, EclipseLink, Hibernate)
Please enable automatic schema generation or create table for storing ID manually when using Table
, Sequence
or IDENTITY
ID Generation.
opt#1. Enable automatic schema generation
<persistence ...>
<persistence-unit ...>
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<properties>
...
<property name="eclipselink.ddl-generation" value="create-tables"/>
...
</persistence-unit>
</persistence>
opt#2. Create table for storing ID manually
Define Sequence in your entity
@SequenceGenerator(name="Emp_Gen", sequenceName="Emp_Seq")
@Id @GeneratedValue(generator="Emp_Gen")
private int getId;
SQL script to create sequence
CREATE SEQUENCE Emp_Seq
MINVALUE 1
START WITH 1
INCREMENT BY 50 //allocation size
来源:https://stackoverflow.com/questions/18529186/eclipselink-jpa-primary-key-with-custom-default-value