使用eclipseLink的异常ResultSet @NamedStoredProcedureQuery

时间:2019-03-01 22:23:50

标签: java oracle spring-data-jpa eclipselink

实现类AttributeConverter时,我需要以下异常的帮助:

java.sql.SQLException: Result Set Closed: next
at oracle.jdbc.driver.InsensitiveScrollableResultSet.next(InsensitiveScrollableResultSet.java:565)
at org.eclipse.persistence.mappings.converters.ConverterClass.convertDataValueToObjectValue(ConverterClass.java:163)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getObjectValue(AbstractDirectMapping.java:619)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.valueFromRow(AbstractDirectMapping.java:1223)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.buildCloneFromRow(AbstractDirectMapping.java:208)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoWorkingCopyClone(ObjectBuilder.java:2007)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneFromRow(ObjectBuilder.java:2260)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:858)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:745)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:699)
at org.eclipse.persistence.queries.EntityResult.getValueFromRecord(EntityResult.java:201)
at org.eclipse.persistence.queries.ResultSetMappingQuery.buildObjectsFromRecords(ResultSetMappingQuery.java:270)
at org.eclipse.persistence.queries.ResultSetMappingQuery.buildObjectsFromRecords(ResultSetMappingQuery.java:239)
at org.eclipse.persistence.internal.jpa.StoredProcedureQueryImpl.getOutputParameterValue(StoredProcedureQueryImpl.java:485)
at org.eclipse.persistence.internal.jpa.StoredProcedureQueryImpl.getOutputParameterValue(StoredProcedureQueryImpl.java:519)

我的转换器课程

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

@Converter
public class CursorConverter implements AttributeConverter<List<String>, ResultSet>{

    @Override
    public ResultSet convertToDatabaseColumn(List<String> attribute) {
        return null;
    }

    @Override
    public List<String> convertToEntityAttribute(ResultSet rs) {
        List<String> companyCodes= new ArrayList<>() ;
        try {
            while(rs.next()) {
                companyCodes.add(rs.getString("CODE_COMPANY"));
            }
            //rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return companyCodes;
    }
}

我的存储库类:

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.query.Procedure;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Transactional(readOnly=true)
@Repository
public interface EmployeeRepository extends JpaRepository<Employee,String>{

    @Procedure(name="Employee.procFind",outputParameterName="EMPL_INFO")
    List<Employee> find(@Param("KEY") String key);

}

我的对象类:

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.NamedStoredProcedureQuery;
import javax.persistence.ParameterMode;
import javax.persistence.QueryHint;
import javax.persistence.StoredProcedureParameter;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.eclipse.persistence.annotations.ConversionValue;
import org.eclipse.persistence.annotations.IdValidation;
import org.eclipse.persistence.annotations.ObjectTypeConverter;
import org.eclipse.persistence.annotations.PrimaryKey;
import org.eclipse.persistence.config.QueryHints;

@Entity
@PrimaryKey(validation=IdValidation.NONE,columns={@Column(name="KEY")})
@NamedStoredProcedureQuery(name = "Employee.procFind", procedureName = "ORACLE.PROC_FIND_EMPLOYEE",hints = {
        @QueryHint(value = "FALSE", name = QueryHints.QUERY_RESULTS_CACHE) },resultClasses = {Employee.class},parameters = {
                @StoredProcedureParameter(name= "KEY" , mode = ParameterMode.IN, type = String.class),
                @StoredProcedureParameter(name = "EMPL_INFO", mode = ParameterMode.REF_CURSOR, type = void.class)})
public class Employee implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Column(name = "KEY_EMPLOYEE")
    private String key;

    @Convert(converter=CursorConverter.class)
    @Column(name = "CURSOR_CODES")
    private List<String> companyCodes;
...
}

这是我的procFind过程

PROCEDURE PROC_FIND_EMPLOYEE (KEY IN  VARCHAR2,EMPL_INFO OUT SYS_REFCURSOR)
BEGIN

      OPEN EMPL_INFO FOR
         SELECT KEY_EMPLOYEE,
                CURSOR_CODES_SOUTH (ROW_ID) CURSOR_CODES,
         FROM EMPLOYEE_NORTH
         WHERE  KEY_EMPLOYEE = KEY
         UNION ALL
         SELECT KEY_EMPLOYEE,
                CURSOR_CODES_NORTH (ROW_ID) CURSOR_CODES,
         FROM EMPLOYEE_SOUTH
         WHERE  KEY_EMPLOYEE = KEY;

END PROC_FIND_EMPLOYEE;

这是我的cursor_codes_south函数

FUNCTION CURSOR_CODES_SOUTH(COM_ID IN VARCHAR2) RETURN SYS_REFCURSOR
IS
  CUR_COM  SYS_REFCURSOR;
  V_SQL VARCHAR2(500);
BEGIN

  V_SQL := 'SELECT  CODE_COMPANY
            FROM    COMPANY_SOUTH
            WHERE   ROW_ID = :b1';

  OPEN CUR_COM FOR V_SQL USING COM_ID;

  RETURN CUR_COM;

END;

你们能帮我吗?

或者另一个解决此问题的方法,因为我无法修改oracle程序。 :(

谢谢。

1 个答案:

答案 0 :(得分:0)

好吧,在StoredProcedureQueryImpl类中查看org.eclipse.persistence.jpa项目的代码,我检查了主ResultSet是否总是关闭。 (第134行):( eclipselink project code