JPA + StoredProcedureCall +对象类型IN参数

时间:2012-02-03 13:10:53

标签: java oracle stored-procedures eclipselink

我正在尝试做一件简单的事情:调用具有对象类型参数的存储过程。

这就是我在db中所拥有的:

create or replace
TYPE TEST_TYPE AS OBJECT 
(
  test_field varchar(100)
)

CREATE OR REPLACE PROCEDURE TEST_PROC 
(
  PARAM1 IN TEST_TYPE 
) AS 
BEGIN
END TEST_PROC;

这就是我在java代码中的内容:

@Embeddable
@Struct(name = "TEST_TYPE", fields = {"TEST_FIELD"})
public class TestStruct
{

    private String testField;

    public String getTestField() {
        return testField;
    }

    public void setTestField(String testField) {
        this.testField = testField;
    }
}

    @PostConstruct
    public void init()
    {

        StoredProcedureCall call = new StoredProcedureCall();
        call.setProcedureName("TEST_PROC");
        call.addNamedArgument("PARAM1", "PARAM1", Types.STRUCT, "TEST_TYPE", TestStruct.class);

        DataReadQuery dataReadQuery = new DataReadQuery(call);
        dataReadQuery.addArgument("PARAM1");

        TestStruct testStruct = new TestStruct();
        List args = new ArrayList();
        args.add(testStruct);

        Object result = ((EntityManagerImpl)em.getDelegate()).getSession().executeQuery(dataReadQuery,args);
    }

这是我在运行时得到的:

Internal Exception: java.sql.SQLException: Invalid column type
Error Code: 17004
Call: BEGIN TEST_PROC(PARAM1=>?); END;
    bind => [1 parameter bound]
Query: DataReadQuery()

我认为我完全不理解使用JPA

的结构主题

请帮助我,好人:)

使这项工作最简短的方法是什么?

4 个答案:

答案 0 :(得分:1)

请发送完整的代码。 对于使用Spring的调用存储过程,您必须扩展StoredProcedure类。如果您发送完整的代码,我可以提供更好的帮助。示例伪代码:

class CustomStoredProcedure extends org.springframework.jdbc.object.StoredProcedure
{
    CustomStoredProcedure()
    {
        super([your-data-source], [package-name]);  
        declareParameter(new SqlParameter([your-struct-name]), Types.STRUCT));
        compile();
    }

    Map<String, Object> execute([your-parameter])
    {
        return super.execute(inputs);
    }
}

为了获得更好的帮助,您已经解释了完整的情况。

答案 1 :(得分:0)

您的代码看起来是正确的。

确保为结构定义了描述符。 (即session.getDescrptor(TestStruct.class))

您可以使用其他类型调用存储过程吗?

您使用的是哪个数据库,是否已将平台正确设置为Oracle?

答案 2 :(得分:0)

似乎跳过@Struct@Embeddable注释类的描述符,除非它们被其他类引用。使其工作的最短路径是使用基于此假设的变通方法。将其他课程放在META-INF/persistence.xml所在的jar中:

@Entity
public class StructEntitiesWorkaround {

  @Id
  private String id;

  private TestStruct testStruct;

}

答案 3 :(得分:0)

您可能希望将SimpleJdbcCallTypes.STRUCT一起使用。

这里是一个示例:https://docs.spring.io/spring-data/jdbc/old-docs/2.0.0.M1/reference/html/orcl.datatypes.html