我有一个使用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.
答案 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而不放弃项目或大规模修改它背后的整个想法。