У меня есть приложение Java, использующее Hibernate 5.1.0
, с пространственными возможностями (geolatte
), работающее на базе Weblogic 12.1.1.0
и Oracle
. У меня есть некоторые источники данных, настроенные с драйвером oracle.jdbc.xa.client.OracleXADataSource
. Это работает нормально в одной среде, но не в другой. При выполнении запроса, я получаю следующую трассировку стека:Пробовал получить OracleConnection, но получил нуль
org.hibernate.HibernateException: java.lang.RuntimeException: Tried retrieving OracleConnection from weblogic.jdbc.wrapper.JTAConnection_weblogic_jdbc_wrapper_XAConnection_oracle_jdbc_driver_LogicalConnection using method getOriginalOwner, but received null.
at org.hibernate.spatial.dialect.oracle.SDOGeometryValueBinder.toNative(SDOGeometryValueBinder.java:88)
at org.hibernate.spatial.dialect.oracle.SDOGeometryValueBinder.bind(SDOGeometryValueBinder.java:53)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:253)
(...)
Caused by: java.lang.RuntimeException: Tried retrieving OracleConnection from weblogic.jdbc.wrapper.JTAConnection_weblogic_jdbc_wrapper_XAConnection_oracle_jdbc_driver_LogicalConnection using method getOriginalOwner, but received null.
at org.geolatte.geom.codec.db.oracle.DefaultConnectionFinder.find(DefaultConnectionFinder.java:75)
at org.geolatte.geom.codec.db.oracle.OracleJDBCTypeFactory.createStruct(OracleJDBCTypeFactory.java:117)
at org.hibernate.spatial.dialect.oracle.SDOGeometryValueBinder.store(SDOGeometryValueBinder.java:72)
Когда я взглянуть на код в geolatte-geom
библиотеке, которая вызывается Hibernate я вижу DefaultConnectionFinder.java, как показано ниже:
for (Method method : con.getClass().getMethods()) {
if (method.getReturnType().isAssignableFrom(
java.sql.Connection.class
)
&& method.getParameterTypes().length == 0) {
try {
method.setAccessible(true);
final Connection oc = find((Connection) (method.invoke(con, new Object[] { })));
if (oc == null) {
throw new RuntimeException(
String.format(
"Tried retrieving OracleConnection from %s using method %s, but received null.",
con.getClass().getCanonicalName(),
method.getName()
)
);
}
return oc;
}
Это получение оболочки соединения, предоставляемой Weblogic, и повторение всех доступных методов с использованием отражения. Он попытается получить фактическое соединение, ищущее метод, который возвращает java.sql.Connection.class
и никаких входных параметров.
Я думаю, что в большинстве случаев метод найденный getConnection
, но в этом случае, как getMethods()
не возвращает значения в определенном порядке, это может быть так, что метод getOriginalOwner
идет первым, который возвращает нуль, и исключение происходит.
Я думаю, здесь мой вопрос в том, думаете ли вы, что я делаю что-то не так, и как я могу избежать этого, или это ошибка Hibernate, и я должен вернуть соединение, когда оно не является нулевым (когда оно равно null I будет просто продолжать с итерацией) или что-то подобное:
final Connection oc = find((Connection) (method.invoke(con, new Object[] { })));
if (oc != null) {
return oc;
}
Hi Karel Maesen, спасибо за ответ, я думаю, что он добавляет ценность. В любом случае, я задаюсь вопросом, почему вы выбрали RuntimeException, как только вы найдете метод, который потенциально может вернуть соединение, но он не выполняет (как в случае с getOriginalOwner), а не выполняет итерацию через остальных кандидатов и проверяет, можете ли вы найти лучше, чем в приведенном выше фрагменте кода. Это был Weblogic 12.1.1.0, показывающий это состояние гонки, поэтому я думал, что эта реализация будет покрыта. – krause