如何在保持之前使用生成的序列号?

时间:2015-05-12 21:59:43

标签: java hibernate jpa

我的情景非常简单。我在entityID类和数据库(Oracle,我不确定这很重要)中有一个@Entity标识字段:

@Id
@SequenceGenerator(name="ENTITY_SEQ_GEN", sequenceName="SEQ_GENERIC", allocationSize = 1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ENTITY_SEQ_GEN")
@Column(name="ENTITY_ID")
private long entityID;

我有一个叫做entityReadableID的另一个字段,它应该是一个字符串,由字符串化的entityID和实体的另一个String字段连接组成。例如。如果entityID是 1234 ,则entityReadableID可能类似于 1234ABC

我的问题是,据我所知,在数据库中创建行之前,不知道entityID的值,但我需要使用其值连接entityReadableID。有没有办法在DB中创建行之前获取序列生成的ID的值,以便我可以使用它来生成其他ID?我知道我可以把它作为一个插入,该字段为null然后在我知道什么是entityID之后进行更新,但该解决方案看起来不那么优雅。

我希望Hibernate / Oracle能够支持这种方式的方式是,如果Hibernate可以某种方式"保留/发布"在实际持久化之前正在处理的实体的下一个生成值,让我知道它是什么,所以我可以用它来操作,然后最后坚持它。

1 个答案:

答案 0 :(得分:0)

您可以通过不直接为该实体使用序列来获取生成的Id之前的实体,我的意思是为该序列使用一个单独的实体,因此您的实体应该是这样的:

SELECT 
    CASE WHEN colVal = 1 THEN 'Male' 
         WHEN colVal = 2 THEN 'Female' 
    END AS `range` ,
    COUNT(*) AS `count` ,
    CASE WHEN colVal = 1 THEN '1' 
         WHEN colVal = 2 THEN '2' 
    END AS 'sort' 
FROM ( SELECT SUM(FI.gender_farmer) as colVal 
       FROM anReference as RF 
         INNER JOIN anFarmerInfo as FI using (ref_id) 
         INNER JOIN anFieldInfo as F using (ref_id) 
         INNER JOIN anSessionExtension as SE using (ref_id) 
         INNER JOIN anExtensionInfo as EI using (extension_id) 
         INNER JOIN tblProvince as LP USING (province_id) 
       WHERE FI.gender_farmer!=0 
         AND RF.date_accessed between '2013-1-1 00:00:00' AND '2015-4-29 23:59:59' 
         AND FI.farmer_name NOT LIKE '%test%' 
         AND FI.farmer_name NOT LIKE '.' 
         AND FI.farmer_name NOT LIKE '' 
         AND FI.farmer_email NOT LIKE '%@email.com%' 
         AND F.field_name NOT LIKE '%test%' 
         AND F.field_name NOT LIKE '.' 
         AND F.field_name NOT LIKE '..' 
         AND EI.extension_email NOT LIKE '%@email.com%' 
         AND EI.extension_name NOT LIKE '%test%' 
         AND EI.extension_name NOT LIKE 'n/a' 
         AND EI.extension_name NOT LIKE 'na' 
         AND EI.extension_name NOT LIKE 'n.a.' 
         AND EI.extension_name NOT LIKE '.' 
         AND EI.extension_name NOT LIKE'' 
         AND CHAR_LENGTH(EI.extension_name)>=2 
         AND RF.category IN (0,5) 
         AND RF.test=1 
       GROUP BY ref_id ) AS summary 
GROUP BY `sort` 
ORDER BY LENGTH(`sort`), `sort`

并且序列的实体类似于:

@Entity
@Table(name = "ENTITY"
)
public class EntityClass implements java.io.Serializable {

    private Long entityId;
    private String entityRelatedId;

    public EntityClass() {
    }
    // you may have other constructors

    @Id
    @Column(name = "ENTITY_ID", nullable = false)
    public Long getEntityId() {
        return this.entityId;
    }

    public void setEntityId(Long entityId) {
        this.entityId = entityId;
    }

    @Column(name = "ENTITY_RELATED_ID", length = 50)
    public String getEntityRelatedId() {
        return this.entityRelatedId;
    }

    public void setEntityRelatedId(String entityRelatedId) {
        this.entityRelatedId = entityRelatedId;
    }

}

现在您可以从序列的实体中获取Id(保留它,您可以回滚该tran或删除它或稍后清空相关表):

@Entity
@Table(name = "SEQ_GENERIC_TBL"
)
public class SeqGenericTbl implements java.io.Serializable {

    private Long id;

    public SeqGenericTbl() {
    }

    public SeqGenericTbl(Long id) {
        this.id = id;
    }

    @Id
    @SequenceGenerator(name = "ENTITY_SEQ_GEN", 
            sequenceName = "SEQ_GENERIC", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ENTITY_SEQ_GEN")
    @Column(name = "ID")
    public Long getId() {
        return this.id;
    }

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

}