2014-11-24 89 views
5

我想創建動態和通用的超類與JPA/hibernate將擴展每個層次結構模型,如:角色,頁面,目錄,部門,權限,樹。 我想用遞歸和Java反射Java hibernate/jpa如何創建自我相關的動態通用實體

應該這樣看這個對象動態樹創建:

enter image description here

該實體應參照自身的實體。

我希望它是完全抽象的,沒有數據庫表。只有擴展的實體應該有db。

我試圖實現這一點。但是失敗那麼久。 Here is my post about it

我考慮的解決方案:

  • @Inheritance(策略= InheritanceType.TABLE_PER_CLASS)
  • @Any和@AnyMetaDef映射
  • @MappedSuperclass
  • @Embeddable和@Embedded

我希望有人會提出一些建議。

+0

在我所有的應用程序,我用來做這個。將共同實體擴展到每個孩子並使用該實體。 – 2014-12-01 05:17:41

+0

你能更精確嗎?你能給我更多的細節嗎?代碼snipest? – masterdany88 2014-12-01 07:28:47

回答

1

我想出了以下設計。您還可以檢查它GitHub

@MappedSuperclass 
public abstract class GenericHierarchicalDictionary { 

    public abstract GenericHierarchicalDictionary getParent(); 

    public abstract Set<? extends GenericHierarchicalDictionary> getChildren(); 

} 

@Entity 
@Table(name = "LocalFolder") 
public class LocalFolder extends GenericHierarchicalDictionary { 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private Long id; 

    @ManyToOne 
    private LocalFolder parent; 

    @OneToMany(mappedBy = "parent") 
    private Set<LocalFolder> children = new HashSet<LocalFolder>(); 

    @Override 
    public LocalFolder getParent() { 
     return parent; 
    } 

    @Override 
    public Set<LocalFolder> getChildren() { 
     return children; 
    } 

    public void addChild(LocalFolder localFolder) { 
     localFolder.parent = this; 
     children.add(localFolder); 
    } 
} 

@Entity 
@Table(name = "RemoteFolder") 
public class RemoteFolder extends GenericHierarchicalDictionary { 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private Long id; 

    @ManyToOne 
    private RemoteFolder parent; 

    @OneToMany(mappedBy = "parent") 
    private Set<RemoteFolder> children = new HashSet<RemoteFolder>(); 

    @Override 
    public RemoteFolder getParent() { 
     return parent; 
    } 

    @Override 
    public Set<RemoteFolder> getChildren() { 
     return children; 
    } 

    public void addChild(RemoteFolder localFolder) { 
     localFolder.parent = this; 
     children.add(localFolder); 
    } 
} 

這是測試:

@Test 
public void testTree() { 
    LOGGER.debug("testAddWebResource"); 
    doInTransaction(new TransactionCallable<Void>() { 
     @Override 
     public Void execute(Session session) { 
      LocalFolder rootLocalFolder = new LocalFolder(); 
      session.persist(rootLocalFolder); 
      LocalFolder localFolder1 = new LocalFolder(); 
      rootLocalFolder.addChild(localFolder1); 
      session.persist(localFolder1); 
      LocalFolder localFolder11 = new LocalFolder(); 
      localFolder1.addChild(localFolder11); 
      session.persist(localFolder11); 

      RemoteFolder rootRemoteFolder = new RemoteFolder(); 
      session.persist(rootRemoteFolder); 
      RemoteFolder remoteFolder1 = new RemoteFolder(); 
      rootRemoteFolder.addChild(remoteFolder1); 
      session.persist(remoteFolder1); 
      RemoteFolder remoteFolder11 = new RemoteFolder(); 
      remoteFolder1.addChild(remoteFolder11); 
      session.persist(remoteFolder11); 
      return null; 
     } 
    }); 
} 
+0

我檢查了您的解決方案。這很好。但是我想把所有常用的方法(getParent(),addChild())放在抽象方法中:'GenericHierarchicalDictionary'。當我把這些方法和參數放到'GenericHierarchicalDictionary'時,我收到一個錯誤:'rg.hibernate.AnnotationException:@OneToOne或@ManyToOne在models.LocalFolder.parent引用一個未知的實體:models.GenericHierarchicalDictionary' – masterdany88 2014-11-27 12:01:58

+0

謝謝。那麼,Hibernate有其侷限性,這就是爲什麼你必須在實際的實現類中顯式聲明依賴關係。總而言之,繼承對於行爲而言比重用數據結構更有意義。 – 2014-11-27 13:17:04

+0

好的。所以讓我們在LocalFolder這樣的混合類中聲明數據結構。但是,我們能不能將父母,孩子,樹結構的方法轉化爲抽象方法(用反思?)?我試圖使通用DAO像許多其他人一樣,但從未看到GenericDao – masterdany88 2014-11-27 13:22:03