【问题标题】:Hibernate Spatial & OSGi休眠空间和 OSGi
【发布时间】:2014-05-24 01:54:26
【问题描述】:

我正在尝试在 OSGi 场景中使用 Hibernate-Spatial,但我很难让它发挥作用。

我正在使用 JBoss Fuse/Fabric8。所以我的东西在 Karaf (2.3.x) 中运行,带有容器管理的事务。 数据库是 PostgresDB (9.3),PostGIS 在 Docker 中运行。



问题:


我的问题是从数据库中检索几何数据类型。我可以持久化实体,但在检索空间数据时总是出现以下错误。

java.lang.IllegalArgumentException: Can't convert object of type org.postgresql.util.PGobject
        at org.hibernate.spatial.dialect.postgis.PGGeometryValueExtractor.toJTS(PGGeometryValueExtractor.java:99)





上下文:


容器中加载的捆绑包:

hibernate-commons-annotations (4.0.4.Final)
hibernate-core (4.2.10.Final)
hibernate-entitymanager (4.2.10.Final)
hibernate-osgi (4.2.10.Final)
JTS Topology Suite (1.12)
Hibernate Spatial (4.0)
PostGIS JDBC driver (1.5.8)
PostgreSQL JDBC4 driver (9.1.902.jdbc4)

实体:

...
      @Column(nullable = false, unique = true)
      @Type(type = "org.hibernate.spatial.GeometryType")
      private Point location;
...

数据源:

  <bean
    id="data_source_postgres" class="org.postgresql.ds.PGPoolingDataSource">
    <property name="serverName" value="serverName" />
    <property name="portNumber" value="portNumber" />
    <property name="databaseName" value="databaseName" />
    <property name="user" value="user" />
    <property name="password" value="password" />
  </bean>

  <service ref="data_source_postgres" interface="javax.sql.DataSource">
    <service-properties>
      <entry key="osgi.jndi.service.name" value="jdbc/postgresds" />
      <entry key="service.exported.interfaces" value="*" />
    </service-properties>
  </service>

persistence.xml:

<persistence-unit name="PU" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/postgresds)</jta-data-source>
    <class>entities.FooEntity</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>            
      <property name="hibernate.dialect" value="org.hibernate.spatial.dialect.postgis.PostgisDialect"/>
      <property name="hibernate.archive.autodetection" value="class, hbm" />
      <property name="hibernate.hbm2ddl.auto" value="create" />
      <property name="hibernate.show_sql" value="true" />
      <property name="hibernate.format_sql" value="true" />
    </properties>
  </persistence-unit>





事实、结论和问题:

  1. 当我在 Karaf 之外针对同一个数据库运行代码时,具有相同的依赖项但使用手动管理的事务,它工作正常。 所以它让我得出结论,问题不是任何依赖项之间的不兼容。如果是这样的话,在卡拉夫外面跑就不行了。

  2. 我已经检查了org.hibernate.spatial.dialect.postgis.PGGeometryValueExtractor.toJTS 的实现,并得出结论认为检索到的对象类型根本不应该是 PGobject!在我的情况下,它应该是一个 org.postgis.Geometry.POINT

  3. 从其他人那里读到类似的帖子我认为适当的数据类型不会被正确注册。但如果是这样的话,它是否可以成功地坚持 Geometry 并且未能检索到它?如何检查哪些数据类型实际上已注册?

  4. 问题的根源是什么?是容器管理事务(Aires)吗?捆绑包是否没有导出所有应有的内容?可能是依赖版本吗?我是否使用了错误的方言/驱动程序/数据源?

【问题讨论】:

    标签: hibernate postgresql osgi postgis apache-karaf


    【解决方案1】:

    解决了。

    我在同一个包中加入了 hibernate-spatial、postgres-jdbc 和 postgis-jdbc 并且 dam 工作正常!

    我会尽快将 Bundle 提交给https://github.com/albertocsm

    【讨论】:

    • 不要认为这是一个好主意,而是应该 postgres-jdbc 对 postgis-jdbc 有一个可选的导入,而 hibernate-special 应该有这些可选的导入。把它包装成一个大块是相当糟糕的。尽管将其作为清洁环境的第一步并找到有问题的捆绑包是有效的。
    • 不适用于导入。还尝试将 post*-jdbc 包作为休眠空间的片段。也没有成功。我认为捆绑隔离机制与 postgis 驱动程序在其上下文中注册的方式不一致(反之亦然)。
    【解决方案2】:

    在 OSGi 中,当您遇到完全没有意义的事情时,检查类加载问题通常很好。

    由于使用完全意外的类型调用该方法(您期望来自 postgis 的对象并从 postgress 收到一个对象)我可以认为在某些时候之前的转换失败了。我会检查是否有多个包导出(或嵌入)单个包,这是此类问题的常见来源。

    【讨论】:

    • 此外,OSGi 通常通过将每个包放在不同的类加载器中来防止注册对象/工厂/转换器;对我来说,它看起来像一个进行转换的包(可能是 Postgres 驱动程序)不导入 org.postgis.Geometry;或等效的,postgis 不注册该数据类型。
    • 因此,在阅读 iocanel 和 Tassos cmets 并重新阅读 Postgis Usage Notes 之后,上面写着“注意 J2EE 容器中的类路径问题,其中 JDBC 驱动程序位于与 Postgis JDBC 扩展不同的类路径和/或Hibernate Spatial.”,我想 postgis-jdbc 注册的数据类型在执行查询时不能用于休眠。我会将 Postgres-jdbc、Potgis-jdbc 和 Hibernate-Spatial 捆绑在一起,看看是否有区别。
    猜你喜欢
    • 2010-10-14
    • 2018-09-08
    • 2015-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-22
    • 1970-01-01
    • 2016-11-11
    相关资源
    最近更新 更多