Hibernate没有使用PostgreSQL序列来生成主键

时间:2014-11-05 09:40:48

标签: hibernate postgresql

我有一个使用Hibernate的Java Server Faces项目将数据存储到PostgreSQL数据库中。

我遇到的问题是Hibernate在将数据保存到数据库时没有考虑现有的序列(fifo_id_seq);它以id = 0;

保存

答案可能非常明显,因为我是Hibernate的新手。

我很抱歉代码很多,但我想发布可能相关的所有内容。

fifo表:

                                    Table "public.fifo"
       Column        |       Type       |                     Modifiers                     
---------------------+------------------+---------------------------------------------------
 id                  | integer          | not null default nextval('fifo_id_seq'::regclass)
 number_of_processes | integer          | 
 total_time          | integer          | 
 average_time        | double precision | 
 average_wait_time   | double precision | 
 total_wait_time     | integer          | 
Indexes:
"fifo_pkey" PRIMARY KEY, btree (id)

fifo_id_seq序列:

         Sequence "public.fifo_id_seq"
    Column     |  Type   |        Value        
---------------+---------+---------------------
 sequence_name | name    | fifo_id_seq
 last_value    | bigint  | 1
 start_value   | bigint  | 1
 increment_by  | bigint  | 1
 max_value     | bigint  | 9223372036854775807
 min_value     | bigint  | 1
 cache_value   | bigint  | 1
 log_cnt       | bigint  | 0
 is_cycled     | boolean | f
 is_called     | boolean | f

FifoEntity.java: *注意:我添加了@Id的构造函数和注释,其余的是生成的

@Entity
@Table(name = "fifo", schema = "public", catalog = "processmanagement")
public class FifoEntity {
private int id;
private Integer numberOfProcesses;
private Integer totalTime;
private Double averageTime;
private Double averageWaitTime;
private Integer totalWaitTime;

public FifoEntity()
{
    // empty
}

public FifoEntity(int numberOfProcesses, int totalTime, double averageTime, double averageWaitTime, int totalWaitTime)
{
    this.numberOfProcesses = numberOfProcesses;
    this.totalTime = totalTime;
    this.averageTime = averageTime;
    this.averageWaitTime = averageWaitTime;
    this.totalWaitTime = totalWaitTime;
}

@Id
@SequenceGenerator(name="fifo_pkey", sequenceName="fifo_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="fifo_pkey")
@Column(name = "id", unique = true, nullable = false)
public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

@Basic
@Column(name = "number_of_processes")
public Integer getNumberOfProcesses() {
    return numberOfProcesses;
}

public void setNumberOfProcesses(Integer numberOfProcesses) {
    this.numberOfProcesses = numberOfProcesses;
}

@Basic
@Column(name = "total_time")
public Integer getTotalTime() {
    return totalTime;
}

public void setTotalTime(Integer totalTime) {
    this.totalTime = totalTime;
}

@Basic
@Column(name = "average_time")
public Double getAverageTime() {
    return averageTime;
}

public void setAverageTime(Double averageTime) {
    this.averageTime = averageTime;
}

@Basic
@Column(name = "average_wait_time")
public Double getAverageWaitTime() {
    return averageWaitTime;
}

public void setAverageWaitTime(Double averageWaitTime) {
    this.averageWaitTime = averageWaitTime;
}

@Basic
@Column(name = "total_wait_time")
public Integer getTotalWaitTime() {
    return totalWaitTime;
}

public void setTotalWaitTime(Integer totalWaitTime) {
    this.totalWaitTime = totalWaitTime;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    FifoEntity that = (FifoEntity) o;

    if (id != that.id) return false;
    if (averageTime != null ? !averageTime.equals(that.averageTime) : that.averageTime != null) return false;
    if (averageWaitTime != null ? !averageWaitTime.equals(that.averageWaitTime) : that.averageWaitTime != null)
        return false;
    if (numberOfProcesses != null ? !numberOfProcesses.equals(that.numberOfProcesses) : that.numberOfProcesses != null)
        return false;
    if (totalTime != null ? !totalTime.equals(that.totalTime) : that.totalTime != null) return false;
    if (totalWaitTime != null ? !totalWaitTime.equals(that.totalWaitTime) : that.totalWaitTime != null)
        return false;

    return true;
}

@Override
public int hashCode() {
    int result = id;
    result = 31 * result + (numberOfProcesses != null ? numberOfProcesses.hashCode() : 0);
    result = 31 * result + (totalTime != null ? totalTime.hashCode() : 0);
    result = 31 * result + (averageTime != null ? averageTime.hashCode() : 0);
    result = 31 * result + (averageWaitTime != null ? averageWaitTime.hashCode() : 0);
    result = 31 * result + (totalWaitTime != null ? totalWaitTime.hashCode() : 0);
    return result;
}
}

在hbm.xml中映射的FifoEntity: *

<class name="com.processmanagement.hibernate.entities.FifoEntity" table="fifo" schema="public" catalog="processmanagement">
    <id name="id" column="id">
        <generator class="sequence-identity">
            <param name="sequence">fifo_id_seq</param>
        </generator>
    </id>
    <property name="numberOfProcesses" column="number_of_processes"/>
    <property name="totalTime" column="total_time"/>
    <property name="averageTime" column="average_time"/>
    <property name="averageWaitTime" column="average_wait_time"/>
    <property name="totalWaitTime" column="total_wait_time"/>
</class>

这就是我尝试使用Hibernate将数据保存到数据库的方式:

    FifoEntity fifoEntity = new FifoEntity(processList.size(), totalTime,
            averageProcessTime, averageWaitTime, totalWaitTime);

    databaseHelper.saveOutcomeToDatabase(fifoEntity);
.
.
.
    public void saveOutcomeToDatabase(Object object)
{
//        session.beginTransaction();
//        session.save(object);
//        session.getTransaction().commit();
    Transaction transaction = session.beginTransaction();
    session.persist(object);
    transaction.commit();
    session.clear();
}

当然,尝试保存连续对象时出错:

org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "fifo_pkey"
  Detail: Key (id)=(0) already exists.

4 个答案:

答案 0 :(得分:2)

为了能够在hibernate实体上使用序列,我们可以使用@SequenceGenerator和@Generated值 例如:

@Id
@Basic(optional = false)
@Column(name = "id")
@SequenceGenerator(name="third_party_seq", sequenceName="third_party_seq",allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="third_party_seq")
private Long id;

我正在使用Hibernate和Postgresql。如需更多参考,我们可以阅读 - http://goo.gl/RQ0Dxg

答案 1 :(得分:1)

刚遇到同样的事情。当使用带有Hibernate的Postgres序列时,不要在与序列一起使用的主键列上设置默认值,因为Hibernate想要设置序列值本身。即。从表定义中删除它:&#34;默认nextval(&#39; fifo_id_seq&#39; :: regclass)&#34;

答案 2 :(得分:1)

如果要使用postgresql默认的SERIAL定义,则必须使用GenerationType.IDENTITY

@Entity
public class Foo {

    @Id
    @GeneratedValue (strategy = GenerationType.IDENTITY)
    private long fooId;

}

要注意的一件事是,正如休眠文档所述,IDENTITY生成会禁用批处理更新。

答案 3 :(得分:0)

经过几个小时的代码搞乱,甚至从头开始重新制作项目,我只是无法让它发挥作用。

结束使用SQL查询将数据保存到数据库,如下所示:

        session.getTransaction().begin();
        SQLQuery sqlQuery = session.createSQLQuery("INSERT into public.fifo" +
                " (number_of_processes, total_time, average_time, average_wait_time, total_wait_time) VALUES " +
                "(" +((FifoEntity) object).getNumberOfProcesses() + ", " +
                ((FifoEntity) object).getTotalTime()+ ", " +
                ((FifoEntity) object).getAverageTime() + ", " +
                ((FifoEntity) object).getAverageWaitTime() + ", " +
                ((FifoEntity) object).getTotalWaitTime() + ");");
       session.getTransaction().commit();

它有点混乱,但它有效并且让我有时间更好地了解Hibernate而不放弃项目或大规模修改它背后的整个想法。