我使用的是GlassFish 3.1.1。和NetBeans 6.9.1。在NetBeans中,我创建了web应用程序并生成了一个实体类。我只添加了@GeneratedValue注释。这是代码:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package entities.worker;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
*
* @author pzielins
*/
@Entity
@Table(name = "cdrconfig", catalog = "cdrworker_db", schema = "public")
@NamedQueries({
@NamedQuery(name = "CdrConfig.findAll", query = "SELECT c FROM CdrConfig c"),
@NamedQuery(name = "CdrConfig.findById", query = "SELECT c FROM CdrConfig c WHERE c.id = :id"),
@NamedQuery(name = "CdrConfig.findByCdrpath", query = "SELECT c FROM CdrConfig c WHERE c.cdrpath = :cdrpath"),
@NamedQuery(name = "CdrConfig.findByWorkerinterval", query = "SELECT c FROM CdrConfig c WHERE c.workerinterval = :workerinterval"),
@NamedQuery(name = "CdrConfig.findByMakebackup", query = "SELECT c FROM CdrConfig c WHERE c.makebackup = :makebackup"),
@NamedQuery(name = "CdrConfig.findByBackuppath", query = "SELECT c FROM CdrConfig c WHERE c.backuppath = :backuppath"),
@NamedQuery(name = "CdrConfig.findByLastsyncdate", query = "SELECT c FROM CdrConfig c WHERE c.lastsyncdate = :lastsyncdate"),
@NamedQuery(name = "CdrConfig.findByWaslastsyncmanual", query = "SELECT c FROM CdrConfig c WHERE c.waslastsyncmanual = :waslastsyncmanual")})
public class CdrConfig implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id", nullable = false)
private Integer id;
@Column(name = "cdrpath", length = 10485760)
private String cdrpath;
@Column(name = "workerinterval")
private Integer workerinterval;
@Column(name = "makebackup")
private Boolean makebackup;
@Column(name = "backuppath", length = 10485760)
private String backuppath;
@Column(name = "lastsyncdate")
@Temporal(TemporalType.TIMESTAMP)
private Date lastsyncdate;
@Column(name = "waslastsyncmanual")
private Boolean waslastsyncmanual;
public CdrConfig() {
}
public CdrConfig(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCdrpath() {
return cdrpath;
}
public void setCdrpath(String cdrpath) {
this.cdrpath = cdrpath;
}
public Integer getWorkerinterval() {
return workerinterval;
}
public void setWorkerinterval(Integer workerinterval) {
this.workerinterval = workerinterval;
}
public Boolean getMakebackup() {
return makebackup;
}
public void setMakebackup(Boolean makebackup) {
this.makebackup = makebackup;
}
public String getBackuppath() {
return backuppath;
}
public void setBackuppath(String backuppath) {
this.backuppath = backuppath;
}
public Date getLastsyncdate() {
return lastsyncdate;
}
public void setLastsyncdate(Date lastsyncdate) {
this.lastsyncdate = lastsyncdate;
}
public Boolean getWaslastsyncmanual() {
return waslastsyncmanual;
}
public void setWaslastsyncmanual(Boolean waslastsyncmanual) {
this.waslastsyncmanual = waslastsyncmanual;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof CdrConfig)) {
return false;
}
CdrConfig other = (CdrConfig) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "entities.worker.CdrConfig[id=" + id + "]";
}
}
然后,我为Entity类生成了一个JPAController类。这是代码:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jpa.worker;
import entities.worker.CdrConfig;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import jpa.exceptions.NonexistentEntityException;
import jpa.exceptions.PreexistingEntityException;
/**
*
* @author pzielins
*/
public class CdrConfigJpaController {
public CdrConfigJpaController() {
emf = Persistence.createEntityManagerFactory("CDRFileWorkerPU");
}
private EntityManagerFactory emf = null;
public EntityManager getEntityManager() {
return emf.createEntityManager();
}
public void create(CdrConfig cdrConfig) throws PreexistingEntityException, Exception {
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
em.persist(cdrConfig);
em.getTransaction().commit();
} catch (Exception ex) {
if (findCdrConfig(cdrConfig.getId()) != null) {
throw new PreexistingEntityException("CdrConfig " + cdrConfig + " already exists.", ex);
}
throw ex;
} finally {
if (em != null) {
em.close();
}
}
}
public void edit(CdrConfig cdrConfig) throws NonexistentEntityException, Exception {
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
cdrConfig = em.merge(cdrConfig);
em.getTransaction().commit();
} catch (Exception ex) {
String msg = ex.getLocalizedMessage();
if (msg == null || msg.length() == 0) {
Integer id = cdrConfig.getId();
if (findCdrConfig(id) == null) {
throw new NonexistentEntityException("The cdrConfig with id " + id + " no longer exists.");
}
}
throw ex;
} finally {
if (em != null) {
em.close();
}
}
}
public void destroy(Integer id) throws NonexistentEntityException {
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
CdrConfig cdrConfig;
try {
cdrConfig = em.getReference(CdrConfig.class, id);
cdrConfig.getId();
} catch (EntityNotFoundException enfe) {
throw new NonexistentEntityException("The cdrConfig with id " + id + " no longer exists.", enfe);
}
em.remove(cdrConfig);
em.getTransaction().commit();
} finally {
if (em != null) {
em.close();
}
}
}
public List<CdrConfig> findCdrConfigEntities() {
return findCdrConfigEntities(true, -1, -1);
}
public List<CdrConfig> findCdrConfigEntities(int maxResults, int firstResult) {
return findCdrConfigEntities(false, maxResults, firstResult);
}
private List<CdrConfig> findCdrConfigEntities(boolean all, int maxResults, int firstResult) {
EntityManager em = getEntityManager();
try {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(CdrConfig.class));
Query q = em.createQuery(cq);
if (!all) {
q.setMaxResults(maxResults);
q.setFirstResult(firstResult);
}
return q.getResultList();
} finally {
em.close();
}
}
public CdrConfig findCdrConfig(Integer id) {
EntityManager em = getEntityManager();
try {
return em.find(CdrConfig.class, id);
} finally {
em.close();
}
}
public int getCdrConfigCount() {
EntityManager em = getEntityManager();
try {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
Root<CdrConfig> rt = cq.from(CdrConfig.class);
cq.select(em.getCriteriaBuilder().count(rt));
Query q = em.createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
} finally {
em.close();
}
}
}
因为我的应用程序需要使用两个数据库,所以我编辑了NetBeans Persistence Unit生成的数据库,现在我有了这样的东西:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="CDRFileWorkerPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/cdrworkerdb</jta-data-source>
<class>entities.config.CdrConfig</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="eclipselink.ddl-generation" value="create-tables"/>
</properties>
</persistence-unit>
<persistence-unit name="CDRDataStorePU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/cdrdb</jta-data-source>
<class>entities.cdr.CallRecord</class>
<class>entities.cdr.RecordColumn</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="eclipselink.ddl-generation" value="create-tables"/>
</properties>
</persistence-unit>
</persistence>
到目前为止一切都很好,但当我尝试在JSF托管Bean中使用此方法时:
public void test() {
try {
CdrConfig cfg = new CdrConfig();
cfg.setBackuppath("foo");
CdrConfigJpaController cjc = new CdrConfigJpaController();
cjc.create(cfg);
Record rec = new Record();
RecordJpaController rjc = new RecordJpaController();
rjc.create(rec);
RecordColumn col = new RecordColumn();
col.setColumnname("foo1");
col.setRecord(rec);
RecordColumnJpaController rcjc = new RecordColumnJpaController();
rcjc.create(col);
} catch (Exception ex) {
Logger.getLogger(FileWorkerBackup.class.getName()).log(Level.SEVERE, null, ex);
}
}
我得到以下错误:
java.lang.IllegalArgumentException: Unknown entity bean class: class entities.worker.CdrConfig, please verify that this class has been marked with the @Entity annotation.
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.find(EntityManagerImpl.java:576)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.find(EntityManagerImpl.java:460)
at jpa.worker.CdrConfigJpaController.findCdrConfig(CdrConfigJpaController.java:125)
at jpa.worker.CdrConfigJpaController.create(CdrConfigJpaController.java:43)
at web.FileWorkerBackup.test(FileWorkerBackup.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at...
我从谷歌了解到,在Persistence Unit编辑器中勾选"在模块中包含所有实体类"有时会很有帮助,但它会给我一些关于表之间的跨数据库引用的错误(我确信我没有尝试这样做)。我在谷歌上也发现,重启glassfish有帮助(因为未关闭的持久性会话),但它也没有帮助。请给我指正确的方向。
也许xml 中的这一行
<class>entities.config.CdrConfig</class>
应该是
<class>entities.worker.CdrConfig</class>