2017-08-04 39 views
0

是否可以从Hibernate(5)中检索实体之间的关系是如何配置的?搞清楚Hibernate是如何配置实体关系的

我的用例如下:我有一个Web服务提供(读取)访问关系数据库中的数据。数据由多个实体组成,其中一些通过外键(通常的一对一,一对多,多对一,多对多)相关联。当请求数据时,客户端可以指定一个过滤器,并且在过滤器中,他们可以自由地遍历实体关系。有些东西需要将过滤器转换成Hibernate理解的东西。目前,我们正在生成Criteria

举例来说,假设我们有2个实体AB,其中A.bees属性指的是B的集合。这在Hibernate中映射为B中的外键列指的是主键A。然后用户可以请求具有至少一个B的所有A和以'Bla'开始的B.name。该请求指定我们正在寻找A类型的结果,它的过滤器部分看起来是这样的:

<like> 
    <property>bees.name</property> 
    <literal>Bla*</literal> 
</like> 

问题是:我的服务不控制Hibernate映射,因此不知道如何关系被配置,甚至存在哪些实体。它只是加载映射,翻译和应用过滤器,并吐出任何由Hibernate返回的数据。我无法按照规范更改请求内容(实际上是OGC筛选器)。

到目前为止,我能够找到合适的实体并遵循属性路径,沿途遇到属性AssociationType s和EntityMetadata并将所有过滤器元素转换为单独的Criterion s。我无法做的是找出实体是如何相关的:在这个例子中,“B有一个外键,指的是主键A”。谁能告诉我如何获得这些信息?

回答

0

原来我误会了如何应该在Hibernate中完成。我用的是标准的API来生成查询,我会写我自己:

session.createCriteria("A") 
     .add(Property.forName("id").in(
       DetachedCriteria.forEntityName("B") 
           .add(Restrictions.like("name", "Bla%")) 
           .setProjection(Projections.property("fk_a")))) 

结果查询是(几乎)

SELECT a.* 
    FROM A a 
WHERE a.id IN (SELECT b.fk_a 
        FROM B b 
       WHERE b.name LIKE 'Bla%') 

问题是我不知道的名字idfk_a


我应该做的而不是(现在正在做)只是让Hibernate做连接。

session.createCriteria("A") 
     .createAlias("B", "b") 
     .add(Restrictions.like("b.name", "Bla%")) 
     .setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE) 

从这个结果查询是(几乎)

SELECT a.*, b.* 
    FROM A a INNER JOIN B b ON a.id = b.fk_a 
WHERE b.name LIKE 'Bla%') 

现在我也不需要知道主键和外键属性的名称。

这种方法的一个明显缺点是,当A和相关B的笛卡尔乘积被返回时,更多的数据从服务器传输到客户端。通过表明我们只对不同的根实体感兴趣,我们得到了预期的答案。虽然变压器在客户端运行,但它确实无助于减少流量。

0

我不知道我很理解你的数据库的访问权限,但如果你能连接到数据库,你可以使用JDBC的DatabaseMetaData的类,它的出口键方法: https://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMetaData.html#getExportedKeys(java.lang.String,%20java.lang.String,%20java.lang.String)

+0

我想避免直接与数据库交谈。原因是:1)Hibernate的配置已经包含了所有必要的细节和2)我将处理不同类型的数据库。 – jackrabbit

+0

hibernate的SessionFactory元数据访问器怎么样? https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/SessionFactory.html 您可以访问'所有类元数据'和类(实体)特定的。 –

+0

感谢您的努力,但是我无法为所有连接类型编写特殊情况下找不到所需的信息。我已经解决了一个不同的方法。 – jackrabbit