所以我有一个实体,由entitymanager和ejb bean管理,并且有一个主键,自动递增,如下所示:
package si.um.jpa.vao;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Vaja {
private int idVaje;
private String nazivVaje, sifraVaje, delTelesa, naprava, opis, slika, video;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public int getIdVaje() {
return idVaje;
}
public void setIdVaje(int idVaje) {
this.idVaje = idVaje;
}
public String getNazivVaje() {
return nazivVaje;
}
public void setNazivVaje(String nazivVaje) {
this.nazivVaje = nazivVaje;
}
public String getSifraVaje() {
return sifraVaje;
}
public void setSifraVaje(String sifraVaje) {
this.sifraVaje = sifraVaje;
}
public String getDelTelesa() {
return delTelesa;
}
public void setDelTelesa(String delTelesa) {
this.delTelesa = delTelesa;
}
public String getNaprava() {
return naprava;
}
public void setNaprava(String naprava) {
this.naprava = naprava;
}
public String getOpis() {
return opis;
}
public void setOpis(String opis) {
this.opis = opis;
}
public String getSlika() {
return slika;
}
public void setSlika(String slika) {
this.slika = slika;
}
public String getVideo() {
return video;
}
public void setVideo(String video) {
this.video = video;
}
@Override
public String toString() {
return "Vaja [idVaje=" + idVaje + ", nazivVaje=" + nazivVaje + ", sifraVaje=" + sifraVaje + ", delTelesa="
+ delTelesa + ", naprava=" + naprava + ", opis=" + opis + ", slika=" + slika + ", video=" + video + "]";
}
}
然后我有管理实体的ejb如下:
package si.um.jpa3.ejb;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import si.um.jpa.vao.Vaja;
import si.um.jpa2.jsf.VajeJSFBean;
@Stateless
public class VajeBean implements VajeBeanLocal {
Logger log=LoggerFactory.getLogger(VajeBean.class);
@PersistenceContext
EntityManager em;
@Override
public void dodajVajo(Vaja v) {
log.info("VajeBean: dodajVajo");
if(najdi(v.getIdVaje())==null)
em.persist(v);
else
em.merge(v);
}
@Override
public List<Vaja> vrniVse() {
log.info("VajeBean: vrniVse");
return em.createQuery("select v from Vaja v").getResultList();
}
@Override
public Vaja najdi(int idVaje) {
log.info("VajeBean: najdi");
System.out.println("najdi: " + idVaje);
return em.find(Vaja.class, idVaje);
}
@Override
public void izbrisi(int idVaje) {
log.info("VajeBean: izbrisi");
em.remove(najdi(idVaje));
}
@Override
public Vaja spremeniInVrni(Vaja v) {
em.detach(v);
Vaja ret = new Vaja();
ret.setDelTelesa(v.getDelTelesa());
ret.setIdVaje(v.getIdVaje());
ret.setNaprava(v.getNaprava());
ret.setNazivVaje(v.getNazivVaje());
ret.setOpis(v.getOpis());
ret.setSifraVaje(v.getSifraVaje());
ret.setSlika(v.getSlika());
ret.setVideo(v.getVideo());
return ret;
}
}
我正在尝试更新Vaja参数,并在此jsfbean中找到id:
package si.um.jpa2.jsf;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ValueChangeEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import si.um.feri.aiv.Klub;
import si.um.feri.aiv.obvescanje.ObvescanjeBeanLocal;
import si.um.jpa.vao.Vaja;
import si.um.jpa3.ejb.VajeBeanLocal;
@ManagedBean(name="zrnoVaje")
//@SessionScoped
public class VajeJSFBean {
Logger log=LoggerFactory.getLogger(VajeJSFBean.class);
private Vaja v = new Vaja();
private Vaja izbranaVaja;
@EJB
VajeBeanLocal vbl;
public void dodajVajo() {
log.info("VajeJSFBean: dodajVajo");
try {
vbl.dodajVajo(v);
v = new Vaja();
} catch (Exception e) {
e.printStackTrace();
};
}
public void spremenjenaVrednost(ValueChangeEvent event) {
String vrednostEventa = (String) event.getNewValue();
System.out.println("spremenjenaVrednost: " + vrednostEventa);
if(vrednostEventa==null)
v = new Vaja();
else {
v = vbl.najdi(Integer.parseInt(vrednostEventa));
}
}
public void izbrisiVajo(int idVaje) {
log.info("VajeJSFBean: izbrisiVajo");
try {
vbl.izbrisi(idVaje);
} catch (Exception e) {
e.printStackTrace();
};
}
public void izberiVajo(int idVaje) {
log.info("VajeJSFBean: izberiVajo");
try {
izbranaVaja = vbl.najdi(idVaje);
} catch (Exception e) {
e.printStackTrace();
};
}
public Vaja getV() {
return v;
}
public void setV(Vaja v) {
this.v = v;
}
public VajeBeanLocal getVbl() {
return vbl;
}
public void setVbl(VajeBeanLocal vbl) {
this.vbl = vbl;
}
public Vaja getIzbranaVaja() {
return izbranaVaja;
}
public void setIzbranaVaja(Vaja izbranaVaja) {
this.izbranaVaja = izbranaVaja;
}
}
这是我的添加/更新页面(dodajVajo.xhtml):
<html
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:jsf="http://xmlns.jcp.org/jsf"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:body>
<ui:composition template="WEB-INF/template/template-trener.xhtml">
<ui:define name="title">
Dodaj/uredi vajo
</ui:define>
<ui:insert name="header">
</ui:insert>
<ui:define name="naslov">
<div style="text-align: center;">
<h1>Dodaj/uredi vajo</h1>
</div>
</ui:define>
<ui:define name="content">
<f:view>
<h:form>
<h:selectOneMenu style="margin:auto; display:block;" onchange="submit()" valueChangeListener="#{zrnoVaje.spremenjenaVrednost}">
<f:selectItem itemLabel="NOVA VAJA"/>
<f:selectItems value="#{zrnoVaje.vbl.vrniVse()}" var="vaja" itemValue="#{vaja.idVaje}" itemLabel="#{vaja.nazivVaje}" />
</h:selectOneMenu>
<br />
</h:form>
<h:form>
<table align="center">
<tr>
<td>ID vaje:</td>
<td><h:inputText id="idVaje" readonly="true" value="#{zrnoVaje.v.idVaje}" required="true"></h:inputText></td>
</tr>
<tr>
<td>Šifra vaje:</td>
<td>
<h:inputText id="sifraVaje" value="#{zrnoVaje.v.sifraVaje}" required="true">
<f:validateLength minimum="2" maximum="45" />
</h:inputText>
</td>
</tr>
<tr>
<td colspan="2"><h:message for="sifraVaje" style="color:red" /></td>
</tr>
<tr>
<td>Naziv vaje:</td>
<td>
<h:inputText id="nazivVaje" value="#{zrnoVaje.v.nazivVaje}" required="true">
<f:validateLength minimum="2" maximum="100" />
</h:inputText>
</td>
</tr>
<tr>
<td colspan="2"><h:message for="nazivVaje" style="color:red" /></td>
</tr>
<tr>
<td>Del telesa:</td>
<td>
<h:inputText id="delTelesa" value="#{zrnoVaje.v.delTelesa}" required="true">
<f:validateLength minimum="2" maximum="45" />
</h:inputText>
</td>
</tr>
<tr>
<td colspan="2"><h:message for="delTelesa" style="color:red" /></td>
</tr>
<tr>
<td>Naprava:</td>
<td>
<h:inputText id="naprava" value="#{zrnoVaje.v.naprava}" required="false">
<f:validateLength minimum="2" maximum="45" />
</h:inputText>
</td>
</tr>
<tr>
<td colspan="2"><h:message for="naprava" style="color:red" /></td>
</tr>
<tr>
<td>Opis:</td>
<td>
<!-- style="resize: none" -->
<h:inputTextarea row="10" col="10" id="opis" value="#{zrnoVaje.v.opis}" required="true">
<f:validateLength minimum="2" maximum="255" />
</h:inputTextarea>
</td>
</tr>
<tr>
<td colspan="2"><h:message for="opis" style="color:red" /></td>
</tr>
<tr>
<td>Slika(URL):</td>
<td>
<h:inputText id="slika" value="#{zrnoVaje.v.slika}" required="false">
<f:validateLength minimum="2" maximum="255" />
</h:inputText>
</td>
</tr>
<tr>
<td colspan="2"><h:message for="slika" style="color:red" /></td>
</tr>
<tr>
<td>Video(URL):</td>
<td>
<h:inputText id="video" value="#{zrnoVaje.v.video}" required="false">
<f:validateLength minimum="2" maximum="255" />
</h:inputText>
</td>
</tr>
<tr>
<td colspan="2"><h:message for="video" style="color:red" /></td>
</tr>
<!--
v nadaljevanju še dropdown z blank prvim za vnos, ostali pa ob izboru prikaže izbranega, ki ga lahko pol uredi
-->
</table>
<br />
<h:commandButton class="btn btn-success" style="margin:auto; display:block;" value="Shrani" actionListener="#{zrnoVaje.dodajVajo}" action="vseVaje.xhtml"/>
</h:form>
</f:view>
</ui:define>
</ui:composition>
</h:body>
</html>
问题如下(我一直在努力解决这个问题)。我更新的条目是重复的(也就是原始的逗留,更新的条目被添加为新的条目)。我已经看过了实体的分离/合并状态以及除此之外的所有状态:
当我从fropdown选择现有的Vaja时,该方法将其设置为JSFBean中的Vaja v(id是正确的 - 1),但是当我更改值然后单击submit(在JSFBean中调用方法dodajVajo)时, id将恢复为原始默认值(0),就像添加新的Vaja一样。所以我的ejbBean正在为一个id为0的Vaja进行搜索,这种情况并不存在,这会导致另一个条件,即只是因为在提交时更改了id(仅因为在提交时更改了id)
任何想法?