【问题标题】:Spring/Hibernate/Oracle: ORA-02289 Sequence Does Not Exist?Spring/Hibernate/Oracle:ORA-02289 序列不存在?
【发布时间】:2016-08-08 14:37:18
【问题描述】:

尝试将新对象插入到我的 Oracle 表中时获取 java.sql.SQLSyntaxErrorException: ORA-02289: sequence does not exist。该表确实有一个在每个条目上自动递增的序列。

我在这个问题上被困了几个小时,在对这个问题和其他文章进行了类似的回答之后,我仍然被困住了。

我的班级:

import java.sql.Timestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

import org.springframework.stereotype.Component;

@Entity
@Table(name = "MY_SCHEMA.MY_TABLE")
@Component
public class SomeClass {
    @Id
    @SequenceGenerator(name = "MY_SEQ", sequenceName = "MY_SEQ", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MY_SEQ")
    @Column(name = "MY_ID")
    private Integer myId;

    @Column(name = "MY_TS")
    private Timestamp ts;

    @Column(name = "MY_PARAM")
    private String myParameters;

    @Column(name = "ANOTHER_TS")
    private Timestamp anotherTimestamp;

    // empty constructor and getters/setters

}

类的 DAO:

import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.springframework.stereotype.Component;

import mypackage.mysubpackage.SomeClass;

@Component
public class SomeClassDAO {

    private Session currentSession;
    private Transaction currentTransaction;

    private static SessionFactory getSessionFactory() {
        Configuration configuration = new Configuration().configure();
        configuration.addAnnotatedClass(SomeClass.class);
        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                .applySettings(configuration.getProperties());
        SessionFactory factory = configuration.buildSessionFactory(builder.build());
        return factory;
    }

    public Session openCurrentSession() {
        currentSession = getSessionFactory().openSession();
        return currentSession;
    }

    public Session openCurrentSessionWithTransaction() {
        currentSession = getSessionFactory().openSession();
        currentTransaction = currentSession.beginTransaction();
        return currentSession;
    }

    public void closeCurrentSession() {
        currentSession.close();
    }

    public void closeCurrentSessionWithTransaction() {
        currentTransaction.commit();
        currentSession.close();
    }

    public Session getCurrentSession() {
        return currentSession;
    }

    public void setCurrentSession(Session currentSession) {
        this.currentSession = currentSession;
    }

    // post
    public void insertNew() {
        SomeClass obj = new SomeClass();
        obj.setParameters("abc");
        getCurrentSession().save(obj);
    }

}

序列的 DDL sn-p:

begin
   if inserting then
      if :NEW."MY_ID" is null then
         select MY_SEQ.nextval into :NEW."MY_ID" from dual;
      end if;
   end if;
end;

hibernate.cfg.xml:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-5.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.url">jdbc:oracle:thin:@servername.company.net:123:ABC</property>
        <property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
        <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <property name="connection.username">user</property>
        <property name="connection.password">pass</property>
        <property name="show_sql">true</property>


    </session-factory>

</hibernate-configuration>

mvc-dispatchet-servlet.xml sn-p:

<context:component-scan base-package="mypackage.mysubpackage"></context:component-scan>
<mvc:annotation-driven/>
<context:annotation-config/>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@servername.company.net:123:ABC"/>
    <property name="username" value="user"/>
    <property name="password" value="pass"/>
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
      p:packagesToScan="mypackage.mysubpackage"
      p:dataSource-ref="dataSource">
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="generateDdl" value="true"/>
            <property name="showSql" value="true"/>
        </bean>
    </property>
</bean>

<bean id="transactionManger" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<tx:annotation-driven transaction-manager="transactionManger"/>

【问题讨论】:

  • 能否确保序列MY_SEQ 位于正确的oracle 架构MY_SCHEMA 中?您可以使用以下命令列出数据库中的所有序列:select SEQUENCE_NAME,MIN_VALUE,MAX_value,LAST_NUMBER,length(LAST_NUMBER) from dba_sequences where SEQUENCE_OWNER=‘schema owner’ order by length(LAST_NUMBER)desc;
  • @MickaëlB 刚刚运行了该语句,是的,它确实出现在 MY_SCHEMA
  • 那么,您可以尝试强制使用@SequenceGenerator(name = "MY_SEQ", sequenceName = "MY_SCHEMA.MY_SEQ", allocationSize = 1) 之类的架构吗?
  • @MickaëlB 现在获得java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist 吗?我将其设置为:@Id @SequenceGenerator(name = "MY_SEQ", sequenceName = "MY_SCHEMA.MY_SEQ", allocationSize = 1) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MY_SEQ") @Column(name = "MY_ID") private Integer myId;

标签: java spring oracle hibernate


【解决方案1】:
begin
   if inserting then
      if :NEW."MY_ID" is null then
         select MY_SEQ.nextval into :NEW."MY_ID" from dual;
      end if;
   end if;
end;

这在我看来像是 oracle trigger 的一部分,而不是实际的 oracle Sequence。检查您的架构中是否确实存在名称为“MY_SEQ”的序列。

如果您的 id 列上有当前 JPA 注释的序列,则不需要触发器。 JPA 本身可以在没有触发器的情况下获取序列下一个值。

如果您仍想继续使用触发器,请阅读here

【讨论】:

    猜你喜欢
    • 2021-09-03
    • 2011-12-31
    • 2015-06-30
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    • 2018-05-15
    相关资源
    最近更新 更多