2012-07-24 64 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