【问题标题】:Entity primary key and sequence实体主键和序列
【发布时间】:2015-03-19 13:27:58
【问题描述】:

我使用 oracle 和 openjpa。 我有一个主键,我想使用一个序列作为它的值

CREATE TABLE LOG (
    ID  NUMBER(10)          not null,
    TIMESTAMP               TIMESTAMP DEFAULT (SYSDATE),
    constraint PK_ID  PRIMARY KEY (ID)
);

CREATE SEQUENCE ID_SEQ
 START WITH     1
 INCREMENT BY   1
 NOCACHE
 NOCYCLE;


@Entity
@Table(name="Log")
public class Log implements Serializable  {
    @Id
    @SequenceGenerator(name="SEQ_GEN", sequenceName="ID_SEQ", allocationSize=1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_GEN" )
    @Column(name="id",nullable=false)
    private long id;

    @Column(name="timestamp",nullable=false)
    private Timestamp timestamp;

    public Log(){
    }

    public Log(Timestamp timestamp){
        this.timestamp = timestamp;
    }
    ..
}

@Stateless
public class LogDAO {

    @PersistenceContext(unitName="logEntityPU")
    private EntityManager em ;


    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public boolean insert(Log log){
      em.persist(log);
      return true;
    }
    ...
    ...
}

当我检查我的 Log 对象时,id=0 并且时间戳没问题

但我收到此错误 ORA-01400: 违反完整性约束: NOT NULL 检查约束。不允许插入空值

这就像 jpa 不做与序列的链接。

当我进行更多调试时,我看到此错误:javax.persistence.TransactionRequiredException: No active transaction for PuId=

有什么想法吗?

【问题讨论】:

  • 在 Oracle 12 之前,您必须先使用命令获取 id,然后才能使用它,或者您需要在表上使用 before insert 触发器来为您插入序列。
  • 尝试使用触发器,结果相同...如果我使用 sql plus 工具手动插入,那可以工作...所以似乎有一个带有 java 代码的程序。
  • 如果触发器不起作用,请提供代码。插入序列的触发器确实有效。我在一个应用程序中有数百个。
  • 问题肯定不是触发因素,就像我写的那样,似乎是事务问题
  • 如果你不显示触发代码我们怎么知道?

标签: oracle primary-key


【解决方案1】:

如果应用没有提供主键,这样的触发器将插入主键

CREATE OR REPLACE TRIGGER YOUR_SCHEMA.TRG_YOUR_TABLE
BEFORE INSERT 
ON YOUR_SCHEMA.YOUR_TABLE
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE
   PrimaryKeyId NUMBER;

BEGIN
      IF :NEW.PRIMARY_KEY_ID IS NULL THEN
         SELECT your_schema.seq_your_table.nextval
         INTO :NEW.PRIMARY_KEY_ID
         FROM dual;
      END IF;

END YOUR_SCHEMA.TRG_YOUR_TABLE;

然后做一个

Select YOUR_SCHEMA.seq_your_table.currval from dual;

获取价值

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-06
    • 2015-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    • 1970-01-01
    相关资源
    最近更新 更多