0

我认为我遇到了一个非常直接的问题,但我无法为 Hibernate 的类提供一个好的结构或找到最佳实践的示例。

我有一个带有映射类测试的表测试。在一个由 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 然后有一些漂亮的继承映射,但那些需要一些标识符,如列或一对一映射表。

编辑:

我尝试过的另一个解决方案是为 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 和 EditQuestion hbm.xml 文件。至少不使用反射(将所有 getter 值从 Question 复制到 AnswerQuestion/EditQuestion 的新实例),这对我来说有点像 hack?我的意思是这似乎不太复杂?

解决方案:我没有让这些类扩展映射的 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);
}
4

1 回答 1

0

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

您是否考虑过在您的 Test 类之上使用 import javax.persistence.Inheritance 注释?

例子:

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

@Entity
public class AdminTest extends Test {
}

更多在这里

于 2012-07-24T16:38:16.863 回答