Spring Data JDBC: DataRetrievalFailureException: невозможно преобразовать [oracle.sql.ROWID] в [java.lang.Number] - PullRequest
0 голосов
/ 17 января 2019

Я новичок в Spring Data JDBC, и я изо всех сил пытаюсь создать простой Dto и сохранить его на БД.

Я использую Spring-Boot 2.1.1.RELEASE и Oracle 12 Database.

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);
}

, и я просто пытаюсь сохранить его на БДвот так

public String createUser() {
    UserDto userDto = new UserDto().setUserName("mapss@sapot.wrong.email.pt").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?Как я могу это исправить?

спасибо всем за помощь.

Ответы [ 3 ]

0 голосов
/ 18 января 2019

К сожалению, Oracle еще не полностью поддерживается. существует проблема, связанная с созданием интеграционных тестов для Oracle , и , сопровождающий PR , уже исправляет некоторые проблемы, но, конечно, не все.

Основная проблема заключается в том, что Oracle делает некоторые интересные вещи, касающиеся генерации сгенерированного ключа. Я вижу следующие варианты

a) Не используйте генерацию ключей на стороне базы данных. DATAJDBC-282 делает это более удобным. Но это пока только в релизе SNAPSHOT.

б) Не используйте Oracle. В настоящее время мы тестируем с MySql, Postgres, H2, HSQLDB и MariaDb

в) Посмотрите на PR, упомянутый выше, чтобы посмотреть, сможете ли вы его исправить, достаточно для работы.

Я знаю, что эти варианты не очень удовлетворяют. Проблема заключается в том, что для проекта с открытым исходным кодом действительно сложно проводить интеграционные тесты с Oracle, поскольку даже загрузка легального драйвера JDBC Oracle из общедоступной сборки CI - это кошмар, не говоря уже о базе данных.

Коллега прислал мне это изображение, когда мы обсуждали ситуацию:

enter image description here

Но мы не сдаемся, будет добавлена ​​надлежащая поддержка.

0 голосов
/ 04 февраля 2019

У меня возникла та же проблема, в то время как PR включается в следующую версию JDBC Spring Data, мы можем использовать следующий обходной путь с Spring AOP. Это не «идеально», но нам достаточно, пока основная проблема не будет решена:

@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 голосов
/ 17 января 2019

Я думаю, вам нужно объявить поле USR_ID и соответствующую последовательность в вашей сущности

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "XXXX")
@SequenceGenerator(sequenceName = "YYYY", allocationSize = 1, name = "XXXX")
Long USR_ID;
...