EclipseLink JPA Primary Key with Custom Default Value

会有一股神秘感。 提交于 2020-08-04 22:49:14

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!