我试图执行一个程序,其中包含一个参数,它是一个对象集合(oracle)。我在没有春天的情况下管理了很多次,但我有点失去了试图用春天来做,虽然在互联网上有一些信息,我找不到一个完整的例子来比较我的代码。 Spring doc只是碎片。可能我的代码是错的,但我忽略了为什么,你能帮帮我吗?我正在运行更简单的程序而没有任何问题。我的DAO看起来像这样:
//[EDITED]
private SimpleJdbcCall pActualizaDia;
....
@Autowired
public void setDataSource(DataSource dataSource) {
pActualizaDia = new SimpleJdbcCall(dataSource).withCatalogName("PTR_GRUPOS_TRABAJO").withProcedureName("UPDATE_DIA");
pActualizaDia.getJdbcTemplate().setNativeJdbcExtractor(new OracleJdbc4NativeJdbcExtractor());
}
...
public Calendario updateSingle(final Calendario calendario) {
SqlTypeValue cambiosEmpresa = new AbstractSqlTypeValue() {
protected Object createTypeValue(Connection conn, int sqlType, String typeName) throws SQLException {
ArrayDescriptor arrayDescriptor = new ArrayDescriptor("TTPTR_CAMBIO_EMPRESA", conn);
Object[] collection = new Object[calendario.getCambiosEmpresa().size()];
int i = 0;
for (CeAnoEmp ce : calendario.getCambiosEmpresa()) {
collection[i++] = new STRUCT(new StructDescriptor("TPTR_CAMBIO_EMPRESA", conn), conn, new Object[] {
ce.getSQLParam1(),
//...more parameters here in order to fit your type.
ce.getSQLparamn() });
}
ARRAY idArray = new ARRAY(arrayDescriptor, conn, collection);
return idArray;
}
};
MapSqlParameterSource mapIn = new MapSqlParameterSource();
mapIn.addValue("P_ID_ESCALA", calendario.getEscala().getIdEscala());
//more simple params here
//Here it is the Oracle ARRAY working properly
pActualizaDia.declareParameters(new SqlParameter("P_CAMBIOS_EMPRESA",
OracleTypes.STRUCT, "TTPR_CAMBIO_EMPRESA"));
mapIn.addValue("P_CAMBIOS_EMPRESA",cambiosEmpresa);
//When executing the procedure it just work :)
pActualizaDia.execute(mapIn);
return null;
}
我得到sais的例外
java.lang.ClassCastException: $Proxy91 cannot be cast to oracle.jdbc.OracleConnection
我一直在阅读有关此主题的更多内容,我发现,如果使用Oracle Arrays,您还必须将连接转换为oracle连接。
但是,大多数Spring jdbc框架类(如SimpleJDBCTemplate和StoredProcedure)都会隐藏您的连接访问权限。我是否需要将其中一个子类化并覆盖某个方法以获取dbcp连接然后将其转换为Oracle连接?
非常感谢。
答案 0 :(得分:1)
我最终解决了这个问题,我编辑了帖子,以便为寻找一段代码来解决这个问题的人提供一个示例。
要记住两件重要的事情:
1)必须在jdbctemplate中设置oracle提取器,以便正确地转换连接以获得oracle功能。
2)当使用这个提取器时,ojdbc和JRE版本必须相同,任何其他情况下你都会得到一个abstractmethodinvocation异常。
感谢任何试图解决它并希望它有所帮助的人。
答案 1 :(得分:1)
你可以使用spring来调用带有oracle结构集合数组的过程:下面是一个简单的例子来做这个
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.sql.DataSource;
import oracle.jdbc.driver.OracleConnection;
import oracle.jdbc.driver.OracleTypes;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.StoredProcedure;
public class SpringObjectMapper {
public static class SaveObjectFunction extends StoredProcedure {
final static Logger logger = LoggerFactory.getLogger(SavePackInterFunction.class);
private static final String PROC_NAME = "schema.proc_name";
private final static String ARRAY_OF_VALUE_PARAM_NAME = "ARRAY_OF_VALUE";
private final static String OUT_PARAM_NAME = "out";
public SaveObjectFunction(DataSource dataSource) {
super(dataSource, PROC_NAME);
declareParameter(new SqlParameter(ARRAY_OF_VALUE_PARAM_NAME, OracleTypes.ARRAY, "schema.array_object_type"));
compile();
}
public String execute(Collection<Model> values) {
logger.info("------------------------EnregInterlocuteurPrcedure::execute : begin----------------------------");
String message = null;
try {
OracleConnection connection = getJdbcTemplate().getDataSource().getConnection().unwrap(OracleConnection.class);
ArrayDescriptor arrayValueDescriptor = new ArrayDescriptor("schema.array_object_type", connection);
StructDescriptor typeObjeDescriptor = new StructDescriptor("schema.object_type", connection);
Object[] valueStructArray = new Object[values.size()];
int i = 0;
for (Iterator<Model> iterator = values.iterator(); iterator.hasNext();) {
Model model = (Model) iterator.next();
STRUCT s = new STRUCT(typeObjeDescriptor, connection, new Object[] {model.getAttribute1(), model.getAttribute2(), model.getAttribute3(),
model.getAttribute4(), model.getAttribute5(), model.getAttribute6(), model.getAttribute7()});
valueStructArray[i++] = s;
}
ARRAY inZoneStructArray = new ARRAY(arrayValueDescriptor, connection, valueStructArray);
Map<String, Object> inputs = new HashMap<String, Object>();
inputs.put(ARRAY_OF_VALUE_PARAM_NAME, inZoneStructArray);
Map<String, Object> out = super.execute(inputs);
message = (String) out.get(OUT_PARAM_NAME);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return message;
}
}
}