2012-07-24 90 views
0

我有一個非常簡單直接的問題,但我不能爲Hibernate類找到一個好的結構或找到最佳實踐的例子。JSF支持bean和Hibernate映射

我有一個表測試映射類測試。在一個由bean控制的頁面中,我列出了用於管理編輯(AdminTest)的所有項目,而在另一個頁面中列出了相同的項目,但是對於具有諸如單選按鈕等影響它們的常規用戶(ShowTest)而沒有改變數據庫。

由於休眠似乎堅持您指定的直接映射類時您檢索與addEntity功能(與經理結束我的班)的項目,感覺就像我被迫做這樣的事情:

class Test { ... } 

class AdminTest extends Test { ... } 

@ManagedBean 
class AdminTestManager { 

    List<AdminTest> items; 

} 

class ShowTest extends Test { ... } 

@ManagedBean 
class ShowTestManager { 

    List<ShowTest> items; 

} 

然後將AdminTest和ShowTest分別映射到具有相同字段的同一個表。這是非常糟糕的,因爲無論何時向表測試添加一個字段,都需要更新這兩個映射。

感覺就像我錯過了這裏的東西,你應該真的只需要一個測試映射到表測試然後有一些漂亮的繼承映射,但那些需要一些標識符像列或一對一映射表。

編輯:

另一種解決方法我試過了具有測試一個映射,仍然有AdminTest和ShowTest繼承了該類,但我用反射來擴展類複製干將。

編輯2:

我會在這裏提供了一個「真實世界」的情況,以便更好地解釋我在問什麼。比方說,我想用一個頁面製作一個測驗引擎,您可以通過輸入字段填寫問題,另一個頁面用每個項目的單選按鈕以「是」或「否」列出這些問題。

的數據庫表會就這樣被創造:

class Question { 

    private int id; 
    private String text; 
    private int correctAnswer; 

    // Getters and setters. 

} 

class EditQuestion extends Question { 

    void updateItem() { ... } 
    void removeItem() { ... } 

} 

@ManagedBean(name = "edit_quiz") 
@ViewScoped 
class EditQuestionManager { 

     List<EditQuestion> items; 
     void addItem() { ... } 
     void init() { 

      items = (ArrayList<EditQuestion>) HibernateUtil.getSessionFactory().getCurrentSession().createSQLQuery("SELECT * FROM question").addEntity(EditQuestion.class) 
    .list(); 

     } 
} 

class AnswerQuestion extends Question { 

    int radioButtonValue; 

    // Getters and setters. 

} 

@ManagedBean(name = "take_quiz") 
@ViewScoped 
class AnswerQuestionManager { 

     List<AnswerQuestion> items; 
     void calculateResults() { ... } 
     void init() { 

      items = (ArrayList<AnswerQuestion>) HibernateUtil.getSessionFactory().getCurrentSession().createSQLQuery("SELECT * FROM question").addEntity(AnswerQuestion.class).list(); 

     } 
} 

然後例如JSF頁面顯示測驗:

CREATE TABLE question (id INT AUTO_iNCREMENT, text VARCHAR, correct_answer INT, primary key(id)); 

,我想我會需要的是這些中的類可能是這樣的:

<ui:repeat value="#{take_quiz.items}" var="question"> 
    <div>#{question.text}</div> 
    <h:selectOneRadio value="#{question.radioButtonValue}" onchange="submit()"> 
     <f:selectItem itemValue="1" itemLabel="Yes" /> 
     <f:selectItem itemValue="0" itemLabel="No" /> 
    </h:selectOneRadio> 
</ui:repeat> 
<h:commandLink action="#{take_quiz.calculateResults()}">Done</h:commandLink> 

現在的問題,至少在我看來,是爲管理視圖和用戶視圖創建這種列表,我需要在hbm.xml文件中將表「問題」映射到AnswerQuestion和EditQuestion。至少不使用反射(將Question中的所有getter-value複製到AnswerQuestion/EditQuestion的新實例),這種感覺對我來說就像是一種黑客攻擊?我的意思是這似乎不太複雜?

解決方案:不是讓類擴展映射的Hibernate表類,而是簡單地添加它們類型的私有屬性。另外,在管理類我遍歷從數據庫中的項目後,他們已經進行檢索和設置列表如下:

ArrayList<Question> tempItems = (ArrayList<Question>) HibernateUtil.getSessionFactory().getCurrentSession().createSQLQuery("SELECT * FROM question").addEntity(Question.class).list(); 
ArrayList<EditQuestion> items = ArrayList<EditQuestion>(); 
for(int i = 0; tempItems.size(); i++) { 
    EditQuestion item = new EditQuestion(); 
    item.setQuestion(tempItems.get(i)); 
    items.add(item); 
} 
+2

爲什麼你需要一個不同的實體,如果它是同一個表?你是不是不正確地在AdminTest而不是AdminTestManager中放置特定於管理視圖的行爲/屬性? – BalusC 2012-07-24 14:43:46

+0

我不確定是否有比「經理」更合適的名稱,雖然他們是代表整個項目集的實體。在JSF中,您通過將AdminTestManager聲明爲託管bean,然後遍歷項目來獲取AdminTestManager。在循環中,我可以從AdminTest對象獲取數據庫字段以及設置不影響數據庫的單選按鈕。它正在工作,但我需要一個單獨的Hibernate映射ShowTest和AdminTest。 – user1540134 2012-07-25 07:46:50

回答

0

我竭力要明白你的問題。你在表達實體的類繼承時遇到麻煩嗎?

您是否考慮過在Test類的頂部使用import javax.persistence.Inheritance註釋?

實施例:

@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public abstract class Test { 
} 

@Entity 
public class AdminTest extends Test { 
} 

更多here

+0

我不確定,但問題的表述方式(*無處可見* JPA或「實體」或類似的字被提及)給我一個強烈的印象,即OP使用的是古老的Hibernate本地API,而不是Hibernate的JPA實現('EntityManager')。 – BalusC 2012-07-24 16:47:45

+0

其實不,看這裏:http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Web_Platform/5/html-single/Hibernate_Entity_Manager_Reference_Guide/index.html,但它看起來像Spring的HibernateTemplate。我只記得讀過它是以前克服的一些Hibernate的問題的一個解決方法。無論如何,我使用SessionFactory來打開和關閉會話,然後使用一些實現開放會話模式的類。我不確定,但如果這會影響我的問題?我會仔細研究它,並試圖澄清我的意思。 – user1540134 2012-07-25 07:07:01

+0

@ 7SpecialGems:我不認爲這是一個繼承問題(它只是一個表有兩種不同的用法,沒有任何像列或子表來分隔它們)。事實上,我懷疑我錯誤地擴展了我的課程。我已經用真實的世界更新了我的問題 - 爲什麼我認爲我需要這樣做。否則,它的工作原理,我試圖解決的問題是我需要兩個子類的單獨映射。 – user1540134 2012-07-25 09:56:01