带有自定义默认值的EclipseLink JPA主键
我的SQL Server数据库中有一个表,其中主键字段是用带有自定义默认值的EclipseLink JPA主键,jpa,eclipselink,Jpa,Eclipselink,我的SQL Server数据库中有一个表,其中主键字段是用NEWID()作为默认值定义的。客户机不需要传递主键字段值,SQL server将处理它 在JPA上定义模型类时,我必须使用生成类型定义这个ID字段。我尝试了IDENTITY、TABLE和SEQUENCE生成器。不幸的是,我得到了一个错误 Exception Description: Error preallocating sequence numbers. The sequence table information is not
NEWID()
作为默认值定义的。客户机不需要传递主键字段值,SQL server将处理它
在JPA上定义模型类时,我必须使用生成类型定义这个ID字段。我尝试了IDENTITY
、TABLE
和SEQUENCE
生成器。不幸的是,我得到了一个错误
Exception Description: Error preallocating sequence numbers.
The sequence table information is not complete..
我的坚持。XML如下所示
<?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>
@Entity
public class OrderHeader implements Serializable {
@Id
@Basic(optional = false)
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="OrderId")
private String orderId;
...
}
我提供了自定义和默认序列ID生成器示例,如下所示 使用自定义序列ID生成器(仅限EclipseLink) 定义自定义序列类
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;
}
}
在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>
使用默认序列ID生成器(JPA、Eclipse、Hibernate)
使用表
、序列
或标识
ID生成时,请启用自动架构生成或创建用于手动存储ID的表
选择#1。启用自动模式生成
<persistence ...>
<persistence-unit ...>
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<properties>
...
<property name="eclipselink.ddl-generation" value="create-tables"/>
...
</persistence-unit>
</persistence>
创建序列的SQL脚本
CREATE SEQUENCE Emp_Seq
MINVALUE 1
START WITH 1
INCREMENT BY 50 //allocation size
Hi@Joe2013不确定是否仍然存在问题,但是当使用表生成器时,并且您没有指定Eclipse链接根据您的对象模型生成架构时,您必须手动创建表,并插入相应生成器的行及其初始值。
否则它将不起作用,您将得到您提到的错误。我做了所有这些。不幸的是,JPA不接受他们。我在数据库中没有序列,因此我无法指定序列名称。能否提供persistence.xml?您好@Joe2013,我没有看到您启用自动模式生成,也没有在代码中设置序列。我已经编辑了我的答案并添加了示例,以启用自动模式生成并设置序列。Hi@study。。我完全按照你说的做了(选项1)。它给了我一个错误/警告,因为标识列“OrderId”必须是int、bigint、smallint、tinyint、decimal或numeric类型的数据,且小数位数必须为0,并且必须约束为不可为空。描述:预分配序列号时出错。序列表信息不完整。正如我前面所说的,我在数据库中的主键是一个uniqueidentifier,它用一个默认值定义为NEWID(),您需要使用类似Identity的东西,因为其他策略有JPA查找并在insert语句中分配序列号,而Identity允许它在插入后从数据库中获取值。请参阅以获取一个简单的示例,并显示您在使用IDENTITY时遇到的完整错误。您还可以尝试将数据库平台指定为用户,因为它使用的是正确的平台:很抱歉,上面的注释没有意识到NEWID()表示您使用的是uniqueidentifier数据库类型,并且我在实体中没有看到字符串。您需要构建自己的NativeSequence实例,并重写getGeneratedValue以处理字符串而不是数字。请参阅上面注释中构建自定义策略的第一个链接。解决方案是创建一个名为sequence的表,并填充:(SEQ_GEN_table,0)。create语句:create TABLE
sequence
(SEQ\u NAME
varchar(50)notnull,SEQ\u COUNT
decimal(38,0)DEFAULT NULL,主键(SEQ\u NAME
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
@SequenceGenerator(name="Emp_Gen", sequenceName="Emp_Seq")
@Id @GeneratedValue(generator="Emp_Gen")
private int getId;
CREATE SEQUENCE Emp_Seq
MINVALUE 1
START WITH 1
INCREMENT BY 50 //allocation size