JSF支持bean和Hibernate映射

时间:2012-07-24 14:36:22

标签: java jsf hibernate-mapping

我认为我有一个相当直接的问题,但我无法为Hibernate的类提供一个很好的结构,或者找到最佳实践的例子。

我有一个带有映射类Test的表测试。在一个由bean控制的页面上,我有一个列表中的所有项目用于管理编辑(AdminTest),而在另一个页面中列出了相同的项目,但对于普通用户而言,使用诸如单选按钮之类的东西来影响它们(ShowTest)而不会改变数据库。

由于Hibernate似乎坚持在使用addEntity函数检索项目时指定一个直接映射的类(在我的类以Manager结尾),感觉就像我被迫做这样的事情:

class Test { ... }

class AdminTest extends Test { ... }

@ManagedBean
class AdminTestManager {

    List<AdminTest> items;

}

class ShowTest extends Test { ... }

@ManagedBean
class ShowTestManager {

    List<ShowTest> items;

}

然后将AdminTest和ShowTest分别映射到具有相同字段的同一个表。这非常糟糕,因为每当我向表测试添加字段时,我都需要更新两个映射。

感觉就像我在这里错过了一些东西,你应该真的只需要一个映射到表测试的Test然后有一些漂亮的继承映射,但那些需要一些标识符,如列或一对一映射表。

编辑:

我尝试过的另一个解决方案是为Test提供一个映射,仍然使用AdminTest和ShowTest扩展该类,但我正在将反射的getter复制到扩展类。

编辑2:

我将在这里提供一个“真实世界”场景,以便更好地解释我在问什么。假设我想制作一个测验引擎,其中一个页面可以通过输入字段填写问题,而另一个页面可以通过每个项目的单选按钮列出这些问题,只需“是”或“否”。

数据库表就像这样创建:

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

我认为我需要的课程是:

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页面可能是这样的:

<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>

现在问题,至少就像我看来的那样,为管理视图和用户视图制作这种列表我需要输入条目将表“问题”映射到AnswerQuestion和hbm.xml文件中的EditQuestion。至少在没有使用反射的情况下(将所有getter值从Question复制到AnswerQuestion / EditQuestion的新实例),这对我来说有点像黑客?我的意思是这似乎并不太复杂?

解决方案:我没有让类扩展映射的Hibernate表类,而只是添加了类型的私有属性。同样在Manager-classes中,我在检索完数据后循环遍历数据库中的项目并设置如下列表:

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);
}

1 个答案:

答案 0 :(得分:0)

我很难理解你的问题。您是否在为实体表达类继承时遇到问题?

您是否考虑在Test类的顶部使用导入javax.persistence.Inheritance注释?

示例:

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

@Entity
public class AdminTest extends Test {
}

更多here

相关问题