在教育JAX-RS和JPA的过程中。当我在Glassfish服务器3.1.2上运行项目时,我偶然发现了以下异常。但是,JPA实现作为独立应用程序正常工作。
内部异常:org.postgresql.util.PSQLException: 错误:关系“producttype_productitem”不存在位置:65错误代码:0调用:SELECT t1。“productCode”,t1.COST, t1.ITEMCODE,t1.ITEMNAME FROM ProductType_ProductItem t0, “ProductItem”t1 WHERE((t0.ProductType_productCode =?)AND (t1。“productCode”= t0.item_productCode))bind => [1参数绑定]
我正在使用Eclipse Kepler IDE,Glassfish Server 3.1.2,Jersey for JAX-RS,Eclipselink 2.3 for JPA Implementation和PostgresSQL for database。
CREATE TABLE "ProductType"
(
"productCode" integer NOT NULL,
"productName" character(50) NOT NULL,
"productType" character(50),
rate numeric(18,6),
count integer,
CONSTRAINT "PrimaryKey" PRIMARY KEY ("productCode")
)
WITH (
OIDS=FALSE
);
ALTER TABLE "ProductType" OWNER TO postgres;
GRANT ALL ON TABLE "ProductType" TO postgres;
GRANT ALL ON TABLE "ProductType" TO public;
CREATE TABLE "ProductItem"
(
"productCode" integer NOT NULL,
"itemCode" character(20),
"itemName" character(20),
"cost" numeric(10,6)
)
WITH (
OIDS=FALSE
);
ALTER TABLE "ProductItem" OWNER TO postgres;
GRANT ALL ON TABLE "ProductItem" TO postgres;
GRANT ALL ON TABLE "ProductItem" TO public;
实体
package com.jaxrs.crud;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.SecondaryTable;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlType;
@Entity
@Table(name="\"ProductType\"")
@XmlType(name = "product")
public class ProductType implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Column(name="\"productType\"")
private String productType;
@Column(name="\"productName\"")
private String productName;
@Id
@Column(name="\"productCode\"")
private String productCode;
private Float rate;
private int count;
@OneToMany(cascade=CascadeType.ALL)
private List<ProductItem> item;
private ProductType(String productID, String productType,
String productName,float rate) {
this.productCode = productID;
this.productType = productType;
this.productName = productName;
this.rate = rate;
ProductItem item1 = new ProductItem();
item1.setCost(new Random().nextFloat());
item1.setItemCode("ITC"+new Random().nextInt());
item1.setItemName("ITN"+new Random().nextInt());
if(item == null )
{
item = new ArrayList<ProductItem>();
}
item.add(item1);
}
public ProductType()
{
}
public ProductType(int count) {
this("PID"+new Random().nextInt(),"PTE"+new Random().nextInt(),"PNE"+new Random().nextInt(),new Random().nextFloat());
this.count = count;
}
/**
* @return the productType
*/
@XmlElement(name = "productCode")
public String getProductType() {
return productType;
}
/**
* @param productType
* the productType to set
*/
public void setProductType(String productType) {
this.productType = productType;
}
/**
* @return the productName
*/
@XmlElement(name = "productName")
public String getProductName() {
return productName;
}
/**
* @param productName
* the productName to set
*/
public void setProductName(String productName) {
this.productName = productName;
}
/**
* @return the productID
*/
@XmlElement(name = "id")
public String getProductID() {
return productCode;
}
/**
* @param productID
* the productID to set
*/
public void setProductID(String productID) {
this.productCode = productID;
}
/**
* @return the rate
*/
@XmlElement(name = "rate")
public Float getRate() {
return rate;
}
/**
* @param rate
* the rate to set
*/
public void setRate(Float rate) {
this.rate = rate;
}
/**
* @return the count
*/
@XmlElement(name = "cnt")
public int getCount() {
return count;
}
/**
* @param count
* the count to set
*/
public void setCount(int count) {
this.count = count;
}
/**
* @return the itemList
*/
@XmlElement(name = "item")
@XmlElementWrapper(name = "items")
public List<ProductItem> getItemList() {
return item;
}
/**
* @param itemList
* the itemList to set
*/
public void setItemList(List<ProductItem> itemList) {
this.item = itemList;
}
@Override
public String toString() {
return new StringBuilder().append(this.productCode).append(" ").append(this.productName).append(" ").append(this.productType).append(" ").append(this.rate).append(" ").append(this.count).toString();
}
}
ProductItem实体
package com.jaxrs.crud;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
@Entity
@Table(name="\"ProductItem\"")
@XmlType(propOrder = { "productCode","itemCode", "itemName", "cost" } )
@XmlAccessorType(XmlAccessType.FIELD)
public class ProductItem {
@Id
@Column(name="\"productCode\"")
private String productCode;
private String itemCode;
private String itemName;
private Float cost;
/**
* @return the itemCode
*/
public String getItemCode() {
return itemCode;
}
/**
* @param itemCode
* the itemCode to set
*/
public void setItemCode(String itemCode) {
this.itemCode = itemCode;
}
/**
* @return the itemName
*/
public String getItemName() {
return itemName;
}
/**
* @param itemName
* the itemName to set
*/
public void setItemName(String itemName) {
this.itemName = itemName;
}
/**
* @return the cost
*/
public Float getCost() {
return cost;
}
/**
* @param cost
* the cost to set
*/
public void setCost(Float cost) {
this.cost = cost;
}
/**
* @return the productCode
*/
public String getProductCode() {
return productCode;
}
/**
* @param productCode the productCode to set
*/
public void setProductCode(String productCode) {
this.productCode = productCode;
}
}
JPA调用
EntityManagerFactory entityManagerFactory = Persistence
.createEntityManagerFactory("jaxrs");
EntityManager em = entityManagerFactory
.createEntityManager();
List<ProductType> results = null;
try {
Query query = em.createQuery("SELECT p FROM ProductType p",
ProductType.class);
results = query.getResultList();
for (ProductType pt : results)
System.out.println(pt);
} catch (Exception e) {
e.printStackTrace();
} finally {
em.close();
entityManagerFactory.close();
}
return results;
答案 0 :(得分:1)
我没有看到如果没有一些更改,它如何在独立工作。 ProductType Entity与ProductItem的@OneToMany(cascade = CascadeType.ALL)关系,它需要一个关系表默认为“ProductType_ProductItem”。
这似乎不正确,因为我发现ProductType和ProductItem都将productCode用作其ID,这一点很奇怪。这似乎是他们之间的OneToOne关系。
无论如何,除非您打算使用关系表,否则OneToMany的设置不正确。应删除或更改它,以便指定要使用的表或连接列。
答案 1 :(得分:1)
我通过更改ProductType类
来修复此问题@OneToMany(cascade=CascadeType.ALL)
private List<ProductItem> item;
到
@OneToMany(orphanRemoval = true)
@JoinColumn(name = "\"productCode\"")
private List<ProductItem> item;
据我所知,JoinColumn应该用于单向关系,以指定持久性提供者foreignKey(这里productCode是ProductItem中的FK)
然而,当我将它作为独立的
运行时,前者仍然有效EntityManagerFactory entityManagerFactory = Persistence
.createEntityManagerFactory("jaxrs");
EntityManager em = entityManagerFactory
.createEntityManager();
List<ProductType> results = null;
try {
Query query = em.createQuery("SELECT p FROM ProductType p",
ProductType.class);
results = query.getResultList();
for (ProductType pt : results)
System.out.println(pt);
} catch (Exception e) {
e.printStackTrace();
} finally {
em.close();
entityManagerFactory.close();
}
return results;
试着分析一下。如果我找到任何东西,我会发布。
感谢。