两天了,我试图让我的JSF + Primefaces / JBoss AS 7.1 / Hibernate应用程序正常工作,我在LazyInitializationException
和Too many tables; MySQL can only use 61 tables in a join
错误之间来回反复。
我将尝试尽可能正确地描述我当前的实体模型。
我有一台由几个模块组成的机器。每个模块基本上都是我的Web应用程序中的一个选项卡,在此选项卡上,表单中有几个字段。问题出在下拉字段中。对于那些,我从drools系统外部获得可用选项,根据其他模块中的其他字段构建选项。例如。可用的颜色取决于所选的表面材质,并相应地创建下拉列表。
现在,由于JSF / Primefaces的限制,我需要将选定的下拉列值保存为模块实体中的对象。有关我的问题,请参阅CustomContent in Primefaces selectOneMenu without persisting object和Disabling items with PrimeFaces SelectOneMenu with custom content / p:column。
因此,对于每个DropDown字段,我在模块实体类中都有@OneToOne
关系:
@Entity
public class PressureModule {
@OneToOne(cascade = CascadeType.ALL)
private Machine machine;
@OneToOne(cascade = CascadeType.ALL)
private DropDownSelectItem type = DropDownSelectItem.getSelectOneItem();
@OneToOne(cascade = CascadeType.ALL)
private DropDownSelectItem pressureTop = DropDownSelectItem.getSelectOneItem();
@OneToOne(cascade = CascadeType.ALL)
private DropDownSelectItem color = DropDownSelectItem.getSelectOneItem();
// getters, setters
}
还有一个DopDownSelectItem:
@Entity
public class DropDownSelectItem implements Serializable, Comparable<DropDownSelectItem> {
@Id
@GeneratedValue
private Long id;
@Column
private String label;
@Column
private String value;
@Column
private boolean disabled;
@Column
private String disabledReason;
}
Hibernate会自动创建以下表格:
CREATE TABLE `dropdownselectitem` (
`id` bigint(20) NOT NULL,
`disabled` tinyint(1) default NULL,
`disabledReason` varchar(255) default NULL,
`label` varchar(255) default NULL,
`value` varchar(255) default NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
CREATE TABLE `pressuremodule` (
`id` bigint(20) NOT NULL,
`machine_id` bigint(20) default NULL,
`pressuretop_id` bigint(20) default NULL,
`color_id` bigint(20) default NULL,
`type_id` bigint(20) default NULL,
PRIMARY KEY (`id`),
CONSTRAINT `FK8E3D129AE7CE7BEF` FOREIGN KEY (`type_id`) REFERENCES `dropdownselectitem` (`id`),
CONSTRAINT `FK8E3D129ABD1E6ED1` FOREIGN KEY (`pressuretop_id`) REFERENCES `dropdownselectitem` (`id`),
CONSTRAINT `FK8E3D129ABD1EE330` FOREIGN KEY (`color_id`) REFERENCES `dropdownselectitem` (`id`),
CONSTRAINT `FK8E3D129AC56471E2` FOREIGN KEY (`machine_id`) REFERENCES `machine` (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
下拉列表中包含以下逻辑:
在.xhtml中:
<p:selectOneMenu value="#{bean.field}" var="x">
<f:selectItems
value="#{dropDownValuesBean.getSelectItems()}" var="dd"
itemLabel="#{dd.label}" itemValue="#{dd}" />
<p:column>
<h:outputText value="#{x.label}" />
<h:outputText value=" {#{x.value}}" />
</p:column>
<p:ajax event="change" update="@form" />
</p:selectOneMenu>
DropDownValuesBean(缩短):
public List<PstSelectItem> getSelectItems(final String module, final String field) {
knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
List<PstSelectItem> returnList;
StatefulKnowledgeSession statefulKnowledgeSession = knowledgeBase.newStatefulKnowledgeSession();
statefulKnowledgeSession.insert(sessionBean.getActiveMachine());
statefulKnowledgeSession.fireAllRules();
Collection<FactHandle> handles = statefulKnowledgeSession.getFactHandles(new ClassObjectFilter(DropDownSelectItem.class));
for (FactHandle handle : handles) {
DropDownSelectItem selectItem = (DropDownSelectItem) statefulKnowledgeSession.getObject(handle);
returnList.add(selectItem);
}
Collections.sort(returnList);
return returnList;
}
现在的问题是,如果我有很多下拉字段(我们说的是最多150个),则会发生以下异常:
javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Too many tables; MySQL can only use 61 tables in a join
原因很清楚,我能理解这个问题。现在,如果我将实体更改为使用@OneToOne( fetch = FetchType.LAZY)
,我会遇到着名的LazyInitializationException
。这并不奇怪。
当我为此搜索解决方案时,我主要获得对Spring框架附带的OpenSessionInView
过滤器的引用。由于我不使用Spring,因为我不计划引入这种依赖,所以我有点迷失。
我已经尝试过以下事项:
@PersistenceContext(type = PersistenceContextType.EXTENDED)
:https://community.jboss.org/thread/177735 DropDownSelectItem
,因为我无法注入相应的Drools逻辑进入实体(@Inject
s)不支持@Entity
环境:
有什么想法吗?如果需要更多关于配置或任何信息的信息,我很乐意提供这些信息!