0

我想创建一个通用的多对多关系(列表)。

使用以下示例域:

+-------+  +----------+ +-----------+
| Issue |  | Web Page | | Wiki Page |  
+-------+  +----------+ +-----------+

我想创建一个如下所示的通用链接关联,其中from可能to是上面的任何域对象。

+---------------------+ 
| Link                |
+---------------------+ 
| Object: from        |
| Object: to          |
| String: description |
+---------------------+ 

如此IssueLink,问题出在关系的一侧。

我设想使用如下所示的链接表:

Link Table
| ID | SRC_ID | SRC_CLASS | DEST_ID | DESC_CLASS |

所以SRC_IDDEST_ID是适当的表中的外键。

Link 表的映射应该是什么样的?

4

2 回答 2

0

Hibernate您不应该从Entity类中手动创建表。只需在您的 pojo 中添加注释@ManyToMany,hibernate 就会生成您的数据库架构,其中包含您与相关表的所有外键关系。

Hibernate 多对多单向映射应该像:

@Entity
class Issue{
  @ManyToMany
  List<Link> links;
}

@Entity
class Link{
}

如果您的应用程序是 Java SE,则使用类SchemaExport在数据库中生成模式。

于 2013-09-29T06:34:32.043 回答
0

我已经通过完全从域对象外部化它来实现这种关系。

示例(Groovy+Grails)

class Link{
   String fromClass
   long fromId
   String toClass
   long toId
   String description

   Link(){}
   Link(Object src, Object dest, String descrption){
      fromClass=src.class.name
      fromId=src.id
      toClass=dest.class.name
      toId=dest.id
      this.description=description
   }

   Object getFrom(){
      // Invoke GORM static finder
      Class.forName(fromClass)."get"(fromId)
   }

   Object getTo(){
      // Invoke GORM static finder
      Class.forName(toClass)."get"(toId)
   }
}

使用关联的服务层来创建/检索对象:

import org.springframework.transaction.annotation.Transactional
class LinkableService {
  @Transactional
  public void link(Object src, Object dest, String description){
    Link link = new Link(src,dest,description)
    link.save()
  }

  @Transactional(readOnly=true)
  public Collection<Link> links(Object subject){
    def fromLinks = Link.findAllWhere(fromClass:subject.class.name, fromId:subject.id)
    def toLinks = Link.findAllWhere(toClass:subject.class.name, toId:subject.id)
    def allLinks = new ArrayList<Link>(fromLinks)
    allLinks.addAll(toLinks)
    return allLinks
  }

}

我有点担心性能,但因为我只希望使用小型数据集,所以它不应该是一个主要问题。如果没有指标,我还不会优化!

但是有更好的解决方案吗?

于 2013-10-05T00:29:23.503 回答