我有一個非常簡單直接的問題,但我不能爲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);
}
爲什麼你需要一個不同的實體,如果它是同一個表?你是不是不正確地在AdminTest而不是AdminTestManager中放置特定於管理視圖的行爲/屬性? – BalusC 2012-07-24 14:43:46
我不確定是否有比「經理」更合適的名稱,雖然他們是代表整個項目集的實體。在JSF中,您通過將AdminTestManager聲明爲託管bean,然後遍歷項目來獲取AdminTestManager。在循環中,我可以從AdminTest對象獲取數據庫字段以及設置不影響數據庫的單選按鈕。它正在工作,但我需要一個單獨的Hibernate映射ShowTest和AdminTest。 – user1540134 2012-07-25 07:46:50