即时使用hibernate 4,spring 4,lucene 3,primefaces 5,java 7.
我有一个数据表,其中的数据填充在烘焙bean上,表中的想法是它向我显示了一些未分类的单词,并让我对它们进行分类。
初始表的示例看起来很正常,例如
1 2 3 4 5
这是我的页面
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:form id="form">
<p:growl id="msgs" showDetail="true" life="2000" />
<p:dataTable id="words" var="word"
value="#{wordCatalogatorController.unknownWords}" editable="true"
style="margin-bottom:20px">
<f:facet name="header">Row Editing</f:facet>
<p:ajax event="rowEdit"
listener="#{wordCatalogatorController.onRowEdit}" update=":form:msgs" />
<p:ajax event="rowEditCancel"
listener="#{wordCatalogatorController.onRowCancel}" update=":form:msgs" />
<p:column headerText="Palabra">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{word.word}" />
</f:facet>
<f:facet name="input">
<h:outputText value="#{word.word}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Tipo Palabra">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{word.wordType}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{word.wordType}" style="width:100%"
converter="#{wordTypeConverter}">
<f:selectItems value="#{wordCatalogatorController.wordTypes}"
var="man" itemLabel="#{man.wordType}" itemValue="#{man}" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:32px">
<p:rowEditor />
</p:column>
</p:dataTable>
</h:form>
</html>
这个bean是:
@Controller
@Transactional
public class WordCatalogatorController {
private List<Word> unknownWords = new ArrayList<Word>();
private List<WordType> wordTypes = new ArrayList<WordType>();
public WordCatalogatorController(){
//inicializamos palabras desconocidas y tipos de palabras!
for(int i = 0 ; i < 6 ; i++){
unknownWords.add(new Word("" + i));
}
for(int i = 0 ; i < 4 ; i++){
wordTypes.add(new WordType("" + i));
}
}
public void onRowEdit(RowEditEvent event) {
Word currentWord = (Word) event.getObject();
unknownWords.remove(currentWord);
}
public void onRowCancel(RowEditEvent event) {
FacesMessage msg = new FacesMessage("Edit Cancelled",
((Word) event.getObject()).getWord());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
if (newValue != null && !newValue.equals(oldValue)) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO,
"Cell Changed", "Old: " + oldValue + ", New:" + newValue);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
然后在编辑并保存第一行(1)后,数据表更新为1 2 2 3 4 5
任何想法都会非常令人沮丧!
这里有pojo clases的代码
@Entity
@Table(name="Word")
@Indexed
@AnalyzerDef(name = "searchtokenanalyzer",tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = StandardFilterFactory.class),
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = StopFilterFactory.class,params = {
@Parameter(name = "ignoreCase", value = "true") }) })
@Analyzer(definition = "searchtokenanalyzer")
public class Word {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long wordId;
@Column(name="word")
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
@Analyzer(definition="searchtokenanalyzer")
private String word;
@ManyToMany(mappedBy="words")
private Collection<Danger> dangers = new ArrayList<Danger>();
@ManyToMany(mappedBy="words")
private Collection<Risk> risks = new ArrayList<Risk>();
@ManyToMany(mappedBy="words")
private Collection<Control> controls = new ArrayList<Control>();
@ManyToOne
@JoinColumn(name = "wordTypeId")
private WordType wordType;
public Word(String word, WordType wordType) {
super();
this.word = word;
this.wordType = wordType;
}
public Word(String word) {
super();
this.word = word;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Word){
return ((Word)obj).getWord().equalsIgnoreCase(this.getWord());
}else{
return false;
}
}
public Word() {
super();
}
public long getWordId() {
return wordId;
}
public void setWordId(long wordId) {
this.wordId = wordId;
}
@Entity
@Table(name = "WordType")
@Indexed
public class WordType {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long wordTypeId;
@Column(name = "wordType")
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
@Analyzer(definition = "searchtokenanalyzer")
private String wordType;
@Column(name = "description")
private String description;
@OneToMany(mappedBy = "wordType")
private Set<Word> words;
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if (!(obj instanceof WordType)) {
return false;
} else {
WordType extenalWT = (WordType) obj;
if (this.wordType.equalsIgnoreCase(extenalWT.getWordType())
&& this.wordTypeId == extenalWT.getWordTypeId()) {
return true;
} else {
return false;
}
}
}
public WordType() {
}
public WordType(String wordType) {
this.wordType = wordType;
}
public long getWordTypeId() {
return wordTypeId;
}
public void setWordTypeId(long wordTypeId) {
this.wordTypeId = wordTypeId;
}
public String getWordType() {
return wordType;
}
public void setWordType(String wordType) {
this.wordType = wordType;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Word> getWords() {
return words;
}
public void setWords(Set<Word> words) {
this.words = words;
}
@Override
public String toString() {
return wordType;
}
}
答案 0 :(得分:2)
对于遇到此问题的其他人:
这似乎是rowEditor和表排序之间的问题。在ajax标记上具有正确的更新目标不是问题,因为技术上删除了行但显示混乱了。只需一点点肮脏,你就可以解决这个问题。您可以在ajax标记的oncomplete期间强制使用过滤器。这将摆脱鬼重复记录。
<p:ajax event="rowEdit"
listener="#{beanName.onRowEdit}"
update=":growl :messages :formName:tableId"
oncomplete="PF('tableWidgetVar').filter();" />
答案 1 :(得分:0)
最后最好的解决方案是为数据表实现select事件,并在事件中有一个对话框来选择选项,然后刷新表,这是最后的xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form id="myForm">
<p:growl id="msgs" showDetail="true" life="2000" />
<p:panel header="Sale Item" style="width: 400px;">
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel value="Texto" for="acSimple" />
<p:autoComplete id="acSimple"
value="#{wordCatalogatorController.texto}"
completeMethod="#{wordCatalogatorController.completeText}"
binding="#{wordCatalogatorController.autoCompleteText}" />
<p:commandButton value="Guardar actividad" id="save"
update=":myForm:msgs words"
binding="#{wordCatalogatorController.saveButton}"
actionListener="#{wordCatalogatorController.saveActivity}"
styleClass="ui-priority-primary" process="@this" />
</h:panelGrid>
<p:dataTable id="words" widgetVar="words" var="word"
value="#{wordCatalogatorController.unknownWords}" editable="true"
style="margin-bottom:20px" rowKey="#{word.word}"
selection="#{wordCatalogatorController.selectedWord}"
selectionMode="single" editMode="row">
<p:ajax event="rowSelect"
listener="#{wordCatalogatorController.changeClient}"
oncomplete="PF('activityDialog').show()"
update=":myForm:activityDialog" />
<f:facet name="header">Edicion de palabras</f:facet>
<p:column headerText="Palabra">
<h:outputText value="#{word.word}" />
</p:column>
<p:column headerText="Edicion">
<h:outputText value="Presione para catalogar la palabra" />
</p:column>
</p:dataTable>
</p:panel>
<p:dialog id="activityDialog" width="500px" height="600px"
header="Palabra a catalogar: #{wordCatalogatorController.selectedWord.word}"
widgetVar="activityDialog" modal="true" closable="false">
<h:panelGrid columns="2" cellpadding="5">
<p:selectOneMenu id="wordTypes"
value="#{wordCatalogatorController.selectedWordType}"
style="width: 150px;" converter="#{wordTypeConverter}">
<p:ajax
listener="#{wordCatalogatorController.wordTypeChangeListener}"
update=":myForm:words" />
<f:selectItem itemLabel="" itemValue="" />
<f:selectItems value="#{wordCatalogatorController.wordTypes}" />
</p:selectOneMenu>
</h:panelGrid>
</p:dialog>
</h:form>
</h:body>
</html>