我有一个非常简单直接的问题,但我不能为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