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

package com.me.data.userservice.models;

import javax.persistence.*;
import java.util.Date;

/**
 * Created by me on 5/27/17.
 */
@Entity
@NamedStoredProcedureQueries({
        @NamedStoredProcedureQuery(name = "getUserDetailsSp",
                procedureName = "user_pkg.get_user_details",
                parameters = {
                        @StoredProcedureParameter(mode = ParameterMode.IN, name = "p_in_user_id", type = Long.class),
                        @StoredProcedureParameter(mode = ParameterMode.IN, name = "p_in_region", type = String.class)
                },
                resultClasses = UserDetails.class)
})
public class UserDetails {
    //region Private members
    @Id
    private Long user_id;
    private String first_name;
    private String last_name;
    private String email;
    @Column(name = "p_in_user_id", nullable = false)
    private String userId;
    private String user_id;
    @Column(name = "p_in_region", nullable = false)
    private String region;
    private Long scnd_user_id;
    ...
}

И хранилище:

package com.me.data.userservice.repositories;

import com.me.data.userservice.models.UserDetails;
import org.springframework.data.jpa.repository.query.Procedure;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;

/**
 * Created by me on 5/27/17.
 */
public interface UserDetailsRepository extends CrudRepository<UserDetails, Long> {
    @Procedure(name="getUserDetailsSp")
    public UserDetails findByUserIdAndRegion(@Param("p_in_user_id") String userId, @Param("p_in_region") String region);
}

Весь этот код компилируется нормально, но когда я вызываю репозиторий, я получаю следующую ошибку:

2017-05-27 18:41:27 ОШИБКА o.a.c.c.C. [. [. [. [DispatcherServlet] - Servlet.service () для сервлета [dispatcherServlet] в контексте с путем [] вызвала исключение [Ошибка обработки запроса; вложенным исключением является org.springframework.dao.InvalidDataAccessApiUsageException: объект класса [org.springframework.data.jpa.repository.query.PartTreeJpaQuery] должен быть экземпляром класса org.springframework.data.jpa.repositedPro. вложенным исключением является java.lang.IllegalArgumentException: объект класса [org.springframework.data.jpa.repository.query.PartTreeJpaQuery] должен быть экземпляром класса org.springframework.data.jpa.repository.query.StoredProcedureJ java.lang.IllegalArgumentException: объект класса [org.springframework.data.jpa.repository.query.PartTreeJpaQuery] должен быть экземпляром класса org.springframework.data.jpa.repository.query.StoredProcedureJpaQueryfra. Assert.instanceCheckFailed (Assert.java:389) в org.springframework.util.Assert.isInstanceOf (Assert.java:327) в org.springframework.util.Assert.isInstanceOf (Assert.java:339) в org.springme .jpa.repository.query.JpaQueryExecution $ PracticeExecution.doExecute (JpaQueryExecution.java:300) в org.springframework.data.jpa.repository.query.JpaQueryExecution.execute (JpaQueryExecution.java:82 at)

По какой-то причине я не могу расшифровать эту ошибку и не могу найти помощь в Google.

Это должно быть возможно, но я не нахожу никаких примеров, которые бы имели более одного возвращаемого значения или параметров только для ввода.

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

Я на самом деле только что понял, что я user_pkg.get_user_details на самом деле функция запроса. Как это меняет мое приложение?

3
Bert Alfred 28 Май 2017 в 03:55

2 ответа

Лучший ответ

Итак, я нашел решение. Я не уверен, что это лучшее решение, но это a .

Сначала я изменил свой репозиторий на стандартный компонент и решил использовать NamedParameterJdbcTemplate и собственный преобразователь строк.

@Component
public class UserDetailsRepository {

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    public UserDetails findByUserIdAndDomain(@Param("p_in_user_id") String userId, @Param("p_in_region") String region) {

        String sql = "select * from TABLE(user_pkg.get_user_details(:p_in_user_id,:p_in_region))";
        MapSqlParameterSource namedParameters = new MapSqlParameterSource("p_in_user_id", userId)
                .addValue("p_in_region", region);
        UserDetails result = (UserDetails)jdbcTemplate.queryForObject(
                sql, namedParameters, new UserDetailsMapper());

        return result;

    }
}

Rowmapper :

import com.me.data.userservice.models.UserDetails;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Created by me on 5/27/17.
 */
public class UserDetailsMapper implements RowMapper {
    @Override
    public Object mapRow(ResultSet resultSet, int i) throws SQLException {
        UserDetails userDetails = new UserDetails();
               userDetails.setAccount_number(resultSet.getString("account_number"));
        userDetails.setCompany_name(resultSet.getString("company_name"));
        ...
        return userDetails;
    }
}
0
Bert Alfred 28 Май 2017 в 15:47

Мое решение или я должен сказать, что мой обходной путь был немного другим, потому что после попытки многих вещей я отказался от @NamedStoredProcedureQueries. Итак, я сделал это с помощью аннотации @Query

@Repository 
public interface MyObjectRepository extends CrudRepository<MyObject, String>  {
    @Query(value = "EXECUTE [dbo].[myProc] :fieldName, :pages", nativeQuery = true)
    Set<MyObject> findAllByFieldName(@Param("fieldName") String fieldName, @Param("pages") int pages);
}

Эта ссылка может быть полезной Хранилища данных в Весенние данные JPA

2
Henry 11 Авг 2017 в 06:08