2015-05-07 2 views
0

У меня есть приложение, работающее с Spring 3.1.1, Hibernate 3.6.0.Final и Hibernate Spatial 1.1.1 на Tomcat 8.0.20. До сих пор мы использовали Oracle 11.2.0.4, но мы хотим перейти на PostgreSQL 9.2-1002.jdbc4/PostGIS 2.1.6.Не найдено соединение Oracle при подключении PostGIS

Мы будем мигрировать схемы базы данных на разных этапах, поэтому на каком-то этапе нам понадобятся некоторые подключения для работы с Oracle, а некоторые с PostGIS. Для того, чтобы начать разработку и тестирование этого я извлекал какую-либо зависимость Oracle Maven и добавил необходимые из них для работы с Postgres, как описано в Hibernate Spatial 1.1.1 Tutorial, в основном:

<dependency> 
    <groupId>org.hibernatespatial</groupId> 
    <artifactId>hibernate-spatial-postgis</artifactId> 
    <version>1.1.1</version> 
</dependency> 

В Tomcat context.xml Я настроил один сингл подключение к настоящему времени:

<Resource accessToUnderlyingConnectionAllowed="true" auth="Container" 
    autoReconnect="true" driverClassName="org.postgresql.Driver" 
    logAbandoned="true" maxWait="5000" minEvictableIdleTimeMillis="60000" 
    name="jdbc/dbname" numTestsPerEvictionRun="3" password="xxx" 
    removeAbandoned="true" removeAbandonedTimeout="60" testOnBorrow="true" 
    testWhileIdle="true" timeBetweenEvictionRunsMillis="60000" 
    type="javax.sql.DataSource" url="jdbc:postgresql://servername:5432/dbname" 
    username="username" validationQuery="select 1" /> 

Это работает нормально. Я могу сначала вставить запись в базу данных с пустым значением в поле «Геометрия», а затем обновить ее с помощью значения координаты для этой точки. Поле определено как:

@Type(type = "org.hibernatespatial.GeometryUserType") 
@Column(name = "geom", columnDefinition="Geometry", nullable = true) 
protected Geometry geom; 

Это работает, без проблем. Проблема приходит, как только я включаю Maven зависимость для Oracle:

<dependency> 
      <artifactId>hibernate-spatial-oracle</artifactId> 
      <groupId>org.hibernatespatial</groupId> 
      <version>1.1.1</version> 
     </dependency> 

Даже если я не настраивайте никаких дополнительных соединения, ни изменить что-либо в моем проекте для того, чтобы использовать Oracle, запись вставляется в Postgres, как ожидалось , но когда дело доходит до обновления поля Geometry, я получаю стек, который вставлен ниже, что является неожиданным «Обнаружением проблемы с Oracle Connection», даже если соединение остается неизменным.

org.hibernatespatial.helper.FinderException: Не удалось получить объект OracleSpatial Connection из PreparedStatement.

Я не могу понять, почему Hibernate сможет вставлять данные в базу данных, но будет искать соединение с Oracle при попытке обновления пространственных данных, только когда я добавлю зависимость от Oracle Maven, которая не должна быть , поскольку я поддерживаю мое соединение, настроенное для PostGIS.

Любая идея о том, что я могу делать неправильно?

Заранее спасибо.

EDIT: Кажется, что при запуске Tomcat и инициализации GeometryUserType метод configure вызывается с нулевыми свойствами. Поэтому по умолчанию используется пространственный диалектик, который будет первым, который он найдет из доступных. Поскольку существует два (Oracle и PostGIS), он просто выберет первый (который, оказывается, является Oracle).

Так что мне нужно что-то упустить в конфигурации, но я подумал, что этого достаточно, чтобы перейти к * persistence.xml * и объявить, что единица персистентности должна использовать этот диалект.

<persistence-unit name="pu_name" transaction-type="JTA"> 
<provider>org.hibernate.ejb.HibernatePersistence</provider> 
     <jta-data-source>${jta.datasource.prefix}datasource_name</jta-data-source> 
     <class>com.myorganization.MyClass</class> 
     <exclude-unlisted-classes>true</exclude-unlisted-classes> 
     <properties> 
      <property name="hibernate.dialect" value="org.hibernatespatial.postgis.PostgisDialect" /> 
(...) 

javax.persistence.PersistenceException: org.hibernate.HibernateException: Problem finding Oracle Connection 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1389) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1317) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1323) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:965) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365) 
    at com.sun.proxy.$Proxy62.flush(Unknown Source) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240) 
    at com.sun.proxy.$Proxy45.flush(Unknown Source) 
    at com.mapflow.geotagdata.common.processing.impl.ProcessorInnerStepsImpl$6.executeTransactionalCommand(ProcessorInnerStepsImpl.java:1056) 
    at com.mapflow.geotagdata.common.processing.impl.ProcessorInnerStepsImpl$6.executeTransactionalCommand(ProcessorInnerStepsImpl.java:1) 
    at com.mapflow.geotagdata.common.transactions.TransactionalCommandExecutor.executeTxRequiresNew(TransactionalCommandExecutor.java:37) 
    at com.mapflow.geotagdata.common.transactions.TransactionalCommandExecutor$$FastClassByCGLIB$$7beb81b5.invoke(<generated>) 
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191) 
    at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622) 
    at com.mapflow.geotagdata.common.transactions.TransactionalCommandExecutor$$EnhancerByCGLIB$$4c535b1b.executeTxRequiresNew(<generated>) 
    at com.mapflow.geotagdata.common.processing.impl.ProcessorInnerStepsImpl.synchPendingTaggedBatchToDB(ProcessorInnerStepsImpl.java:1012) 
    at com.mapflow.geotagdata.common.processing.impl.ProcessorInnerStepsImpl.access$0(ProcessorInnerStepsImpl.java:996) 
    at com.mapflow.geotagdata.common.processing.impl.ProcessorInnerStepsImpl$5.call(ProcessorInnerStepsImpl.java:969) 
    at com.mapflow.geotagdata.common.processing.impl.ProcessorInnerStepsImpl$5.call(ProcessorInnerStepsImpl.java:1) 
    at com.mapflow.geotagdata.common.processing.utility.RetryOnExceptionBuilder.execute(RetryOnExceptionBuilder.java:96) 
    at com.mapflow.geotagdata.common.processing.impl.ProcessorInnerStepsImpl.dataTaggingPhase(ProcessorInnerStepsImpl.java:964) 
    at com.mapflow.geotagdata.common.processing.impl.ProcessorOuterStepsImpl.doOuterStepLineByLineInnerSteps(ProcessorOuterStepsImpl.java:107) 
    at com.mapflow.geotagdata.common.processing.impl.ProcessorImpl.process(ProcessorImpl.java:149) 
    at com.mapflow.geotagdata.common.processing.impl.ProcessorImpl.processFile(ProcessorImpl.java:80) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) 
    at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:80) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: org.hibernate.HibernateException: Problem finding Oracle Connection 
    at org.hibernatespatial.oracle.OracleJDBCTypeFactory.createStruct(OracleJDBCTypeFactory.java:38) 
    at org.hibernatespatial.oracle.SDOGeometry.store(SDOGeometry.java:154) 
    at org.hibernatespatial.oracle.SDOGeometryType.conv2DBGeometry(SDOGeometryType.java:88) 
    at org.hibernatespatial.oracle.SDOGeometryType.nullSafeSet(SDOGeometryType.java:77) 
    at org.hibernatespatial.GeometryUserType.nullSafeSet(GeometryUserType.java:201) 
    at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:140) 
    at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2184) 
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2559) 
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2495) 
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2822) 
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:113) 
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:185) 
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) 
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) 
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:962) 
    ... 44 more 
Caused by: org.hibernatespatial.helper.FinderException: Couldn't get at the OracleSpatial Connection object from the PreparedStatement. 
    at org.hibernatespatial.oracle.DefaultConnectionFinder.find(DefaultConnectionFinder.java:82) 
    at org.hibernatespatial.oracle.DefaultConnectionFinder.find(DefaultConnectionFinder.java:68) 
    at org.hibernatespatial.oracle.DefaultConnectionFinder.find(DefaultConnectionFinder.java:68) 
    at org.hibernatespatial.oracle.DefaultConnectionFinder.find(DefaultConnectionFinder.java:51) 
    at org.hibernatespatial.oracle.OracleJDBCTypeFactory.createStruct(OracleJDBCTypeFactory.java:36) 
    ... 61 more 

ответ

0

Как прокомментировал, мне казалось, что Hibernate по умолчанию будет spatialDialect, который будет первым находит из имеющихся, и в этом случае это был Oracle, несмотря на то, что было указано в persistence.xml.

Первое решение, которое я нашел для аннотирования в сущности, для GeometryUserType я бы использовать PostGIS диалект, как в:

@TypeDefs({@TypeDef(name="org.hibernatespatial.GeometryUserType", 
     parameters={@org.hibernate.annotations.Parameter(name="dialect",value="org.hibernatespatial.postgis.PostgisDialect")}, 
     typeClass=org.hibernatespatial.GeometryUserType.class)}) 

Это заставит Hibernate использовать PostGIS для этого объекта.

Второй способ обхода, который работал лучше для меня (я должен иметь возможность настроить это и использовать разные диалекты для одного объекта в зависимости от единицы персистентности и среды) - использовать файл сопоставления в блоке персистентности.

<persistence-unit name="persistence_unit_name" transaction-type="JTA"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 
    <jta-data-source>jta_data_source_name</jta-data-source> 
    <mapping-file>${hibernate.mappingfile}</mapping-file> 
    <class>(...)</class> 

В моем файле пом, я буду делать, что отображение файла в один, что мне нужно, используя Maven профили и переменные.

<hibernate.mappingfile>oracle.hbm.xml</hibernate.mappingfile> 

Или:

<hibernate.mappingfile>postgis.hbm.xml</hibernate.mappingfile> 

Так что я бы, например, postgis.hbm.xml файл:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD//EN" 
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping> 
    <typedef name="org.hibernatespatial.GeometryUserType" class="org.hibernatespatial.GeometryUserType" > 
     <param name="dialect">org.hibernatespatial.postgis.PostgisDialect</param> 
    </typedef> 
</hibernate-mapping> 

И в oracle.hbm.xml:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD//EN" 
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping> 
    <typedef name="org.hibernatespatial.GeometryUserType" class="org.hibernatespatial.GeometryUserType" > 
     <param name="dialect">org.hibernatespatial.oracle.OracleSpatial10gDialect</param> 
    </typedef> 
</hibernate-mapping> 

Интересно, если есть лучший способ сделать это, но никого, что я мог бы найти в эти дни, или что мне ответили здесь. Надеюсь, что это помогает кому-то.

Смежные вопросы