Postgres数据库表中的列未自动填充

时间:2012-05-22 21:12:53

标签: hibernate postgresql insert

我使用hibernate连接到Postgres数据库。在数据库中有一个表,其中一列设置为存储在该表中插入记录时的当前时间。当我从Postgres界面插入记录时,将自动填充当前时间。

但是当我尝试从Hibernate插入记录时,数据库不会自动在当前时间列中插入记录。

Query dateQuery=session.createQuery("select b.boilerPlateContent from Boiler_Plates b join b.bt_contracts c where c.contractId=:val order by b.boilerPlateContent desc)").setEntity("val",ct);
Iterator dateIterator = dateQuery.list().iterator();
String latestBoilerPlate=(String)dateIterator.next();
System.out.println(latestBoilerPlate);
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher(latestBoilerPlate);
while(m.find()){
 lastEntered=m.group();
 nextBoilerPlateNumber=Integer.parseInt(m.group());
}
nextBoilerPlateNumber++;
Boiler_Plates  bp=new Boiler_Plates();
bp.setBoiler_plate_id(boilerPlateId);
boilerPlateText="bp"+nextBoilerPlateNumber;
bp.setBoilerPlateContent(boilerPlateText);
bp.setBoilerPlateName("Test");
//bp.setInsertTime();
bp.setContract(ct);
session.save(bp);
tx.commit(); 

2 个答案:

答案 0 :(得分:2)

您似乎正在尝试进行审核。有一些非常完善的解决方案,你应该使用而不是自己动手。使用envers查看trigger examples on the PostgreSQL wiki@PrePersist, @PreUpdate, and entity listeners和JPA审核支持。更好的是,使用@Embeddable实体和@EntityListener,这样您就可以重用审计代码。

您尚未指定自动设置列的方式。

如果您设置了DEFAULT,那么Hibernate会为INSERT上的所有列指定值,因此DEFAULT将不被使用。您需要获取Hibernate以避免设置列或显式指定关键字DEFAULT作为列值 - 您可以通过将其映射为insertable = false,updatable = false来完成此操作。或者,您需要让Hibernate直接插入您想要的值。

另一种选择是使用ON INSERT FOR EACH ROW触发器来设置列的值。这使得您可以设置PL / PgSQL中的值,无论有人在INSERT时为列指定了什么。

这是another entity listener example

答案 1 :(得分:0)

正如已经指出的那样,您最初的问题中的信息非常缺乏。但假设“当我插入记录时自动填充当前时间”意味着您在该列上定义了DEFAULT,DEFAULT值仅在insert语句中未引用该列时生效。默认情况下,Hibernate将引用insert语句中的所有列。但是,您可以更改该行为。在这里,您正在寻找类似于此映射的内容:

@Entity
public class Boiler_Plates {
    ...
    @Temporal(TemporalType.TIMESTAMP)
    @Generated(GenerationTime.INSERT) 
    @Column(insertable = false)
    Date insertTime
}

@Column(insertable = false)表示不在INSERT语句中包含此列。 @Generated(GenerationTime.INSERT)表示在执行INSERT后重新读取该列的状态以查找生成的值。