GenerationType.SEQUENCE 休眠时不生成序列
GenerationType.SEQUENCE does not generate sequence in hibernate
这是我的实体文件:-
@Entity
@Table(name = "tbl_article_function_instruction_status")
@XmlRootElement
public class ArticleFonctionInstructionStatuts extends BaseEntity implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AFIS_Sequence")
@SequenceGenerator(allocationSize = 5000, name="AFIS_Sequence", sequenceName="AFIS_Sequence")
@Basic(optional = false)
@Column(name = "art_fun_ins_status_id")
private Integer afiStaIndex;
@Basic(optional = false)
@Column(name = "art_fun_ins_status_date")
@Temporal(TemporalType.TIMESTAMP)
private Date afiStaDate;
}
我试过了 GenerationType.SEQUENCE
& GenerationType.AUTO
.
但是在 GenerationType.SEQUENCE
的情况下,它会给我一个错误:-
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1239)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access0(EntityManagerFactoryBuilderImpl.java:120)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.perform(EntityManagerFactoryBuilderImpl.java:855)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.perform(EntityManagerFactoryBuilderImpl.java:845)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:844)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1627)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1564)
... 42 more
Caused by: org.hibernate.MappingException: Could not instantiate id generator [entity-name=com.alstom.autofie.entity.ArticleFonctionInstructionStatuts]
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:123)
at org.hibernate.mapping.SimpleValue.createIdentifierGenerator(SimpleValue.java:213)
at org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:323)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1859)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.perform(EntityManagerFactoryBuilderImpl.java:852)
... 50 more
Caused by: org.hibernate.MappingException: com.alstom.autofie2.dao.CustomSQLDialect does not support sequences
at org.hibernate.dialect.Dialect.getSequenceNextValString(Dialect.java:882)
at org.hibernate.id.SequenceGenerator.configure(SequenceGenerator.java:110)
at org.hibernate.id.SequenceHiLoGenerator.configure(SequenceHiLoGenerator.java:55)
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:117)
... 54 more
这里的 CustomSQLDialect 是 class 扩展了 SQLServerDialect。
在 GenerationType.AUTO
的情况下,它在插入多条记录时给我一个错误,因为它始终生成相同的键,而不是顺序键。
DEBUG IdentifierGeneratorHelper - Natively generated identity: 0
我在sql服务器上验证过,AFIS_Sequence每次都在生成序列。这意味着休眠配置存在一些问题。
是否遗漏了任何配置或者是hibernate的错误?
根据 Hibernate 4.x 文档,我们有:
GeneratorType.AUTO
This is the default strategy and is portable across different databases. Hibernate
chooses the appropriate ID based on the database.
对于 GeneratorType.AUTO
你的 table 必须有一个 Auto Incremented Primary Key
。
我们还有:
GeneratorType.SEQUENCE
Some databases provide a mechanism of sequenced numbers, so this setting will let
Hibernate use the sequence number.
我看到的是你没有正确指定 Hibernate 应该使用哪个序列,按照这个例子:
public class Employee {
@Id
@Column(name="EMPLOYEE_ID")
@GeneratedValue (strategy= GenerationType.SEQUENCE, generator="empSeqGen")
@SequenceGenerator(name = "empSeqGen", sequenceName = "EMP_SEQ_GEN")
private int employeeId =0;
...
}
您需要在数据库中创建一个序列并将其指定给您的 bean。
编辑:
我正在添加更多信息:
The strategy is defined as a SEQUENCE, and accordingly the generator is given a reference
to a sequence generator, empSeqGen, which refers to a sequence object in the database.
Using the @SequenceGenerator, we reference EMP_SEQ_GEN, which is a sequence object
created in the database.
CustomSQLDialect
应该扩展 SQLServer2012Dialect
,因为以前的版本不支持序列。
当您使用
@GeneratedValue(strategy=GenerationType.AUTO)
您正在使用具有休眠功能的自动增量,但是如果您使用
@GeneratedValue(strategy=GenerationType.IDENTITY)
您将使用数据库的自动增量
import java.util.Date;
import javax.persistence.*;
@Entity
@Table(name="driver_license")
public class DriverLicense extends License {
private String driverLicenseName;
@Temporal(TemporalType.DATE)
private Date driverLicenseExpiryDate;
@Temporal(TemporalType.DATE)
private Date driverLicenseIssueDate;
public String getDriverLicenseName() {
return driverLicenseName;
}
public void setDriverLicenseName(String driverLicenseName) {
this.driverLicenseName = driverLicenseName;
}
public Date getDriverLicenseExpiryDate() {
return driverLicenseExpiryDate;
}
public void setDriverLicenseExpiryDate(Date driverLicenseExpiryDate) {
this.driverLicenseExpiryDate = driverLicenseExpiryDate;
}
public Date getDriverLicenseIssueDate() {
return driverLicenseIssueDate;
}
public void setDriverLicenseIssueDate(Date driverLicenseIssueDate) {
this.driverLicenseIssueDate = driverLicenseIssueDate;
}
}
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.SequenceGenerator;
@MappedSuperclass
public class License {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="license_gen")
@SequenceGenerator(name="license_gen",sequenceName="lic_seq_gen",initialValue=1,allocationSize=1)
protected int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory sessionFactory ;
static{
Configuration configuration=new Configuration();
configuration.addAnnotatedClass(DriverLicense.class);
// configuration.addAnnotatedClass(DriverLicense.class);
configuration.setProperty("connection.driver_class","org.postgresql.Driver");
configuration.setProperty("hibernate.connection.url", "jdbc:postgresql://localhost:5432/test");
configuration.setProperty("hibernate.connection.username", "postgres");
configuration.setProperty("hibernate.connection.password", "postgres");
configuration.setProperty("dialect", "org.hibernate.dialect.PostgreSQLDialect");
configuration.setProperty("hibernate.hbm2ddl.auto", "update");
configuration.setProperty("hibernate.show_sql", "true");
configuration.setProperty(" hibernate.connection.pool_size", "10");
StandardServiceRegistryBuilder registry=new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory=configuration.buildSessionFactory(registry.build());
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
public class Main {
public static void main(String[] args) {
DriverLicense driverLicense=new DriverLicense();
driverLicense.setDriverLicenseExpiryDate(new Date());
driverLicense.setDriverLicenseName("License for all");
driverLicense.setDriverLicenseIssueDate(new Date());
Session session=HibernateUtil.getSessionFactory().openSession();
try {
session.beginTransaction();
session.save(driverLicense);
session.getTransaction().commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
尝试使用@GeneratedValue(strategy=GenerationType.IDENTITY)
.
但我建议了解每个人的作用:
- AUTO:表示持久性提供者应该选择一个
针对特定数据库的适当策略。
- IDENTITY:表示持久性提供者必须分配primary
使用数据库标识列的实体键。
- SEQUENCE:表示持久化提供者必须分配primary
使用数据库序列的实体键。
- TABLE:表示持久化提供者必须分配primary
使用基础数据库 table 的实体的密钥以确保
唯一性。
更多信息请访问documentation。
这是我的实体文件:-
@Entity
@Table(name = "tbl_article_function_instruction_status")
@XmlRootElement
public class ArticleFonctionInstructionStatuts extends BaseEntity implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AFIS_Sequence")
@SequenceGenerator(allocationSize = 5000, name="AFIS_Sequence", sequenceName="AFIS_Sequence")
@Basic(optional = false)
@Column(name = "art_fun_ins_status_id")
private Integer afiStaIndex;
@Basic(optional = false)
@Column(name = "art_fun_ins_status_date")
@Temporal(TemporalType.TIMESTAMP)
private Date afiStaDate;
}
我试过了 GenerationType.SEQUENCE
& GenerationType.AUTO
.
但是在 GenerationType.SEQUENCE
的情况下,它会给我一个错误:-
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1239) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access0(EntityManagerFactoryBuilderImpl.java:120) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.perform(EntityManagerFactoryBuilderImpl.java:855) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.perform(EntityManagerFactoryBuilderImpl.java:845) at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:844) at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1627) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1564) ... 42 more Caused by: org.hibernate.MappingException: Could not instantiate id generator [entity-name=com.alstom.autofie.entity.ArticleFonctionInstructionStatuts] at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:123) at org.hibernate.mapping.SimpleValue.createIdentifierGenerator(SimpleValue.java:213) at org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:323) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1859) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.perform(EntityManagerFactoryBuilderImpl.java:852) ... 50 more Caused by: org.hibernate.MappingException: com.alstom.autofie2.dao.CustomSQLDialect does not support sequences at org.hibernate.dialect.Dialect.getSequenceNextValString(Dialect.java:882) at org.hibernate.id.SequenceGenerator.configure(SequenceGenerator.java:110) at org.hibernate.id.SequenceHiLoGenerator.configure(SequenceHiLoGenerator.java:55) at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:117) ... 54 more
这里的 CustomSQLDialect 是 class 扩展了 SQLServerDialect。
在 GenerationType.AUTO
的情况下,它在插入多条记录时给我一个错误,因为它始终生成相同的键,而不是顺序键。
DEBUG IdentifierGeneratorHelper - Natively generated identity: 0
我在sql服务器上验证过,AFIS_Sequence每次都在生成序列。这意味着休眠配置存在一些问题。
是否遗漏了任何配置或者是hibernate的错误?
根据 Hibernate 4.x 文档,我们有:
GeneratorType.AUTO This is the default strategy and is portable across different databases. Hibernate chooses the appropriate ID based on the database.
对于 GeneratorType.AUTO
你的 table 必须有一个 Auto Incremented Primary Key
。
我们还有:
GeneratorType.SEQUENCE Some databases provide a mechanism of sequenced numbers, so this setting will let Hibernate use the sequence number.
我看到的是你没有正确指定 Hibernate 应该使用哪个序列,按照这个例子:
public class Employee {
@Id
@Column(name="EMPLOYEE_ID")
@GeneratedValue (strategy= GenerationType.SEQUENCE, generator="empSeqGen")
@SequenceGenerator(name = "empSeqGen", sequenceName = "EMP_SEQ_GEN")
private int employeeId =0;
...
}
您需要在数据库中创建一个序列并将其指定给您的 bean。
编辑:
我正在添加更多信息:
The strategy is defined as a SEQUENCE, and accordingly the generator is given a reference to a sequence generator, empSeqGen, which refers to a sequence object in the database. Using the @SequenceGenerator, we reference EMP_SEQ_GEN, which is a sequence object created in the database.
CustomSQLDialect
应该扩展 SQLServer2012Dialect
,因为以前的版本不支持序列。
当您使用
@GeneratedValue(strategy=GenerationType.AUTO)
您正在使用具有休眠功能的自动增量,但是如果您使用
@GeneratedValue(strategy=GenerationType.IDENTITY)
您将使用数据库的自动增量
import java.util.Date;
import javax.persistence.*;
@Entity
@Table(name="driver_license")
public class DriverLicense extends License {
private String driverLicenseName;
@Temporal(TemporalType.DATE)
private Date driverLicenseExpiryDate;
@Temporal(TemporalType.DATE)
private Date driverLicenseIssueDate;
public String getDriverLicenseName() {
return driverLicenseName;
}
public void setDriverLicenseName(String driverLicenseName) {
this.driverLicenseName = driverLicenseName;
}
public Date getDriverLicenseExpiryDate() {
return driverLicenseExpiryDate;
}
public void setDriverLicenseExpiryDate(Date driverLicenseExpiryDate) {
this.driverLicenseExpiryDate = driverLicenseExpiryDate;
}
public Date getDriverLicenseIssueDate() {
return driverLicenseIssueDate;
}
public void setDriverLicenseIssueDate(Date driverLicenseIssueDate) {
this.driverLicenseIssueDate = driverLicenseIssueDate;
}
}
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.SequenceGenerator;
@MappedSuperclass
public class License {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="license_gen")
@SequenceGenerator(name="license_gen",sequenceName="lic_seq_gen",initialValue=1,allocationSize=1)
protected int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory sessionFactory ;
static{
Configuration configuration=new Configuration();
configuration.addAnnotatedClass(DriverLicense.class);
// configuration.addAnnotatedClass(DriverLicense.class);
configuration.setProperty("connection.driver_class","org.postgresql.Driver");
configuration.setProperty("hibernate.connection.url", "jdbc:postgresql://localhost:5432/test");
configuration.setProperty("hibernate.connection.username", "postgres");
configuration.setProperty("hibernate.connection.password", "postgres");
configuration.setProperty("dialect", "org.hibernate.dialect.PostgreSQLDialect");
configuration.setProperty("hibernate.hbm2ddl.auto", "update");
configuration.setProperty("hibernate.show_sql", "true");
configuration.setProperty(" hibernate.connection.pool_size", "10");
StandardServiceRegistryBuilder registry=new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory=configuration.buildSessionFactory(registry.build());
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
public class Main {
public static void main(String[] args) {
DriverLicense driverLicense=new DriverLicense();
driverLicense.setDriverLicenseExpiryDate(new Date());
driverLicense.setDriverLicenseName("License for all");
driverLicense.setDriverLicenseIssueDate(new Date());
Session session=HibernateUtil.getSessionFactory().openSession();
try {
session.beginTransaction();
session.save(driverLicense);
session.getTransaction().commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
尝试使用@GeneratedValue(strategy=GenerationType.IDENTITY)
.
但我建议了解每个人的作用:
- AUTO:表示持久性提供者应该选择一个 针对特定数据库的适当策略。
- IDENTITY:表示持久性提供者必须分配primary 使用数据库标识列的实体键。
- SEQUENCE:表示持久化提供者必须分配primary 使用数据库序列的实体键。
- TABLE:表示持久化提供者必须分配primary 使用基础数据库 table 的实体的密钥以确保 唯一性。
更多信息请访问documentation。