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