春季数据JDBC:DataRetrievalFailureException:无法施放[oracle.sql.ROWID]至[java.lang.Number中]

问题描述 投票:1回答:3

我是新来春数据JDBC,我很努力创建一个简单的DTO,并把它坚持在DB。

我使用的弹簧引导2.1.1.RELEASE并和Oracle数据库12。

UserDto

@Table(value="USERS_T")
public class UserDto extends PersistableDto {
    @Id
    @Column(value="USR_USERNAME")
    private String userName;

    @Column(value="USR_FIRSTNAME")
    private String firstName;

    @Column(value="USR_LASTNAME")
    private String lastName; 
.....
}

userDAO的

@Repository
public interface UserDao extends CrudRepository<UserDto, String> {

    @Query("SELECT * FROM USERS_T u WHERE u.USR_USERNAME = :userName")
    UserDto findByUserName(@Param("userName") String userName);
}

而我只是想坚持它在DB这样

public String createUser() {
    UserDto userDto = new UserDto().setUserName("[email protected]").setPassword("superpass").setUserType("Guest").setActive(true);
    logger.info(String.format("Creating user: " + userDto));

    userDto.setNew(true);
    UserDto persistedUser = userDao.save(userDto);

    logger.info(String.format("Persisted user: " + persistedUser));
    return "Ending of create user operation";
}

我得到这个例外。

org.springframework.dao.DataRetrievalFailureException: The generated key is not of a supported numeric type. Unable to cast [oracle.sql.ROWID] to [java.lang.Number]
        at org.springframework.jdbc.support.GeneratedKeyHolder.getKey(GeneratedKeyHolder.java:79) ~[spring-jdbc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
        at org.springframework.data.jdbc.core.DefaultDataAccessStrategy.getIdFromHolder(DefaultDataAccessStrategy.java:323) ~[spring-data-jdbc-1.0.3.RELEASE.jar:1.0.3.RELEASE]

我认为,这在某种程度上是事实,@Id是一个字符串相关。

有人可以帮助我了解我究竟做错了什么?为什么这种行为。关于规范我没有看到,并限制该ID的类型。这是和Oracle融合问题?我怎样才能解决这个问题?

谢谢大家的帮助。

java spring spring-data spring-jdbc spring-data-jdbc
3个回答
2
投票

不幸的是,甲骨文还没有完全支持。有an issue open for creating integration tests for Oracleaccompanying PR已经修复了一些问题,但肯定不是全部。

这里的主要问题是,甲骨文不会产生关于密钥生成一些有趣的东西。我看到下面的选项

a)不要在数据库端使用密钥生成。 DATAJDBC-282使得这个更舒适。但是,至今只在快照版本。

B)不要使用Oracle。目前,我们与MySQL,Postgres的,H2,HSQLDB和MariaDB的测试

C)看看上面提到的,看看是否能足够的工作修补它的PR。

我知道,这些选项都不是很令人满意。我们面临的挑战是,它真的很难为一个开源项目做与Oracle集成测试,因为即使从公共CI构建下载合法的Oracle JDBC驱动程序是一个恶梦,更何况是一个数据库。

一个同事给我发了,当我们在讨论局势的图像:

enter image description here

但我们没有放弃,适当的支持将增加。


1
投票

我遭遇了同样的问题,而被列入明年春天数据JDBC版本中,我们可以使用Spring AOP实现以下解决方法的PR,直到潜在的问题就解决了这不是我们的“完美”,但不够:

@Around("execution(public * my-app-pacakage.repository.*.save(..))")
public Object aspectController(ProceedingJoinPoint jp) throws Throwable {
    try {
        return jp.proceed();
    } catch (DbActionExecutionException e) {
        if (e.getCause() instanceof DataRetrievalFailureException) {
            return jp.getArgs()[0];
        }
        return e;
    } catch(Throwable e) {
        throw e;        
    }       
}

0
投票

我认为你需要声明在实体的USR_ID领域和相应的序列

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "XXXX")
@SequenceGenerator(sequenceName = "YYYY", allocationSize = 1, name = "XXXX")
Long USR_ID;
© www.soinside.com 2019 - 2024. All rights reserved.