【问题标题】:Oracle 12c Identity column with Hibernate 5带有 Hibernate 5 的 Oracle 12c 身份列
【发布时间】:2015-08-14 06:45:41
【问题描述】:

我正在尝试将 Oracle 12c 身份列 功能与 Hibernate-5.0.0.CR4 一起使用。我在 Spring boot application.properties 中使用了以下属性:

spring.jpa.hibernate.dialect=org.hibernate.dialect.Oracle12cDialect
spring.datasource.driverClassName=oracle.jdbc.OracleDriver

Oracle12cDialectsource code 看来,它似乎支持标识列。但是在尝试将记录插入到名为user_preferences 的表中时出现以下错误:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.envers.Audited;
import org.hibernate.envers.RelationTargetAuditMode;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import lombok.Data;

@Entity
@Table(name = "user_preferences")
@Data
@JsonIgnoreProperties(value = { "prefId" })
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
public class UserPreference {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "pref_id")
    private Long prefId;

    @Column(nullable = false)
    private String key;

    @Column(nullable = false)
    private String preference;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    public UserPreference() {
    }

    public UserPreference(String key, String preference, User user) {
        this.key = key;
        this.preference = preference;
        this.user = user;
    }

}   

我遇到的异常

java.sql.SQLException: Invalid column type: getLong not implemented for class oracle.jdbc.driver.T4CRowidAccessor
    at oracle.jdbc.driver.GeneratedAccessor.getLong(GeneratedAccessor.java:436)
    at oracle.jdbc.driver.GeneratedStatement.getLong(GeneratedStatement.java:228)
    at oracle.jdbc.driver.GeneratedScrollableResultSet.getLong(GeneratedScrollableResultSet.java:564)
    at org.hibernate.id.IdentifierGeneratorHelper.get(IdentifierGeneratorHelper.java:113)
    at org.hibernate.id.IdentifierGeneratorHelper.getGeneratedIdentity(IdentifierGeneratorHelper.java:73)
    at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:88)
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:42)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2730)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3300)
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:474)
    at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:179)
    at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:163)
    at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:198)
    at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:317)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:272)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:178)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:109)
    at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67)
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:774)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:747)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:752)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1146)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:344)
    at com.sun.proxy.$Proxy106.persist(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:291)
    at com.sun.proxy.$Proxy106.persist(Unknown Source)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:433)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:436)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:421)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:393)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$DefaultMethodInvokingMethodInterceptor.invoke(RepositoryFactorySupport.java:506)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy117.save(Unknown Source)
    at nl.yestelecom.phoenix.user.preference.UserPreferenceService.saveUserPreference(UserPreferenceService.java:45)
    at nl.yestelecom.phoenix.controller.UserController.saveUserPreference(UserController.java:34)

请告诉我是否有办法在不使用数据库序列的情况下使用标识列。

【问题讨论】:

  • 您找到问题的答案了吗?
  • 不,很遗憾,我没有。我们使用 Oracle db 序列来生成 id。
  • 好的,花了几个小时后,它对我有用 oracle 12c、ojdbc7-12.1.0.2.0.jar、@GeneratedValue(strategy = GenerationType.IDENTITY) 和 spring.jpa.database-platform= org.hibernate.dialect.Oracle12cDialect,spring boot 2.0.3.RELEASE 具有 hibernate-core-5.2.17.Final-sources.jar
  • 感谢您的评论 gargkshitiz,我发现我已经将旧方言留在了我的 persistence.xml 中……为我节省了几个小时!

标签: spring oracle jpa oracle12c hibernate-5.x


【解决方案1】:

当您指定 GenerationType.IDENTITY 时,Hibernate 5.0.X 似乎会尝试从数据库中获取 ID 值。该值是使用适当的 getXXX 从 java ResultSet 中检索的,具体取决于您用于声明 ID 的类型。 resultSet.getString(columnIndex) 或 resultSet.getRowId(columnIndex) 在我的情况下工作,但 RowId 不能在 JPA bean 中使用。

如果您尝试将其 ID 更改为字符串,它应该可以工作,即使它在我看来像是一个错误:

@Id
@Column(name="PRD_ID")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private String prdId; 

【讨论】:

    【解决方案2】:

    你可以这样做:

    创建表 identity_test_tab ( id 号码默认生成为身份, 说明 VARCHAR2(30) );

    SQL> INSERT INTO identity_test_tab (description) VALUES ('Just DESCRIPTION');

    已创建 1 行。

    SQL> INSERT INTO identity_test_tab (id, description) VALUES (999, 'ID=999 and DESCRIPTION');

    已创建 1 行。

    SQL> INSERT INTO identity_test_tab (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION'); INSERT INTO identity_test_tab (id, description) VALUES (NULL, 'ID=NULL and DESCRIPTION') * 第 1 行的错误: ORA-01400: 无法将 NULL 插入 ("TEST"."IDENTITY_TEST_TAB"."ID")

    因为始终标识列的值不应为空

    【讨论】:

    • 我的问题是我应该如何使用 Hibernate 来做到这一点。我对一般如何使用 oracle Identity 列类型非常熟悉。
    猜你喜欢
    • 2016-11-14
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    • 2020-01-06
    • 2016-06-27
    • 2016-02-15
    • 2019-07-08
    • 2020-03-20
    相关资源
    最近更新 更多