簡體   English   中英

帶有OpenJPA實體和聯結表的Spring JPA映射(多對多)

[英]Spring JPA mapping with OpenJPA entities with junction table (many-to-many)

我在映射由聯結表聯接的JPA實體時遇到問題。 使用OpenJPA 2.3.0實現(Spring 4.0.2,Spring data jpa 1.5.0)通過STS 3.4.0創建實體。 它似乎確實在執行數據庫命中並返回數據,但是在將數據序列化為JPA實體時存在問題。 實體是使用字段訪問“渴望”生成的。

庫:

interface MenuItemRepository extends JpaRepository<MlMenuItem, Short>

調用repository.findAll(); (實際上發生在任何添加/獲取中)我得到以下錯誤:

org.springframework.orm.jpa.JpaSystemException:org.apache.openjpa.util.ShortId無法轉換為com.xxxxxxxxx.jpa.model.cafe.MlMenuItem

如果我生成“惰性” bean,並且從不訪問與其關聯的項(也就是foodItems),則它的工作原理很好。 如果有幫助,我對JPA還是很陌生,所以可能很明顯,但是非聯接表可以正常工作,因此不確定對此表。

以下是JPA實體和配置:

第一實體:

@Entity
@Table
(name="ML_MENU_ITEM")
@NamedQuery
(name="MlMenuItem.findAll", query="SELECT m FROM MlMenuItem m")
public class MlMenuItem implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="MENU_ITEM_NBR", unique=true, nullable=false)
private short menuItemNbr;
@Column(name="COMPLETED_IND", nullable=false, length=1)
private String completedInd;
@Column(name="MARKET_PRICE_IND", nullable=false, length=1)
private String marketPriceInd;
@Column(name="MENU_ITEM_DES", nullable=false, length=100)
private String menuItemDes;
@Column(name="MENU_ITEM_NAME", nullable=false, length=40)
private String menuItemName;
@OneToMany(mappedBy="mlMenuItem", fetch=FetchType.EAGER)
private List<MlMenuFoodItem> mlMenuFoodItems;
@ManyToOne
@JoinColumn(name="MENU_TYPE_CD")
private MlMenuType mlMenuType;
@ManyToOne
@JoinColumn(name="MENU_ITEM_CLS_CD", nullable=false)
private MlMnuItmClsTyp mlMnuItmClsTyp;
@OneToMany(mappedBy="mlMenuItem", fetch=FetchType.EAGER)
private List<MlMenuItemPrice> mlMenuItemPrices;
@OneToMany(mappedBy="mlMenuItem", fetch=FetchType.EAGER)
private List<MlOrdMnuItm> mlOrdMnuItms;
public MlMenuItem() {
}
public short getMenuItemNbr() {
return this.menuItemNbr;
}
public void setMenuItemNbr(short menuItemNbr) {
this.menuItemNbr = menuItemNbr;
}
public String getCompletedInd() {
return this.completedInd;
}
public void setCompletedInd(String completedInd) {
this.completedInd = completedInd;
}
public String getMarketPriceInd() {
return this.marketPriceInd;
}
public void setMarketPriceInd(String marketPriceInd) {
this.marketPriceInd = marketPriceInd;
}
public String getMenuItemDes() {
return this.menuItemDes;
}
public void setMenuItemDes(String menuItemDes) {
this.menuItemDes = menuItemDes;
}
public String getMenuItemName() {
return this.menuItemName;
}
public void setMenuItemName(String menuItemName) {
this.menuItemName = menuItemName;
}
public List<MlMenuFoodItem> getMlMenuFoodItems() {
return this.mlMenuFoodItems;
}
public void setMlMenuFoodItems(List<MlMenuFoodItem> mlMenuFoodItems) {
this.mlMenuFoodItems = mlMenuFoodItems;
}
public MlMenuFoodItem addMlMenuFoodItem(MlMenuFoodItem mlMenuFoodItem) {
getMlMenuFoodItems().add(mlMenuFoodItem);
mlMenuFoodItem.setMlMenuItem(
this);
return mlMenuFoodItem;
}
public MlMenuFoodItem removeMlMenuFoodItem(MlMenuFoodItem mlMenuFoodItem) {
getMlMenuFoodItems().remove(mlMenuFoodItem);
mlMenuFoodItem.setMlMenuItem(
null);
return mlMenuFoodItem;
}
public MlMenuType getMlMenuType() {
return this.mlMenuType;
}
public void setMlMenuType(MlMenuType mlMenuType) {
this.mlMenuType = mlMenuType;
}
public MlMnuItmClsTyp getMlMnuItmClsTyp() {
return this.mlMnuItmClsTyp;
}
public void setMlMnuItmClsTyp(MlMnuItmClsTyp mlMnuItmClsTyp) {
this.mlMnuItmClsTyp = mlMnuItmClsTyp;
}
public List<MlMenuItemPrice> getMlMenuItemPrices() {
return this.mlMenuItemPrices;
}
public void setMlMenuItemPrices(List<MlMenuItemPrice> mlMenuItemPrices) {
this.mlMenuItemPrices = mlMenuItemPrices;
}
public MlMenuItemPrice addMlMenuItemPrice(MlMenuItemPrice mlMenuItemPrice) {
getMlMenuItemPrices().add(mlMenuItemPrice);
mlMenuItemPrice.setMlMenuItem(
this);
return mlMenuItemPrice;
}
public MlMenuItemPrice removeMlMenuItemPrice(MlMenuItemPrice mlMenuItemPrice) {
getMlMenuItemPrices().remove(mlMenuItemPrice);
mlMenuItemPrice.setMlMenuItem(
null);
return mlMenuItemPrice;
}
public List<MlOrdMnuItm> getMlOrdMnuItms() {
return this.mlOrdMnuItms;
}
public void setMlOrdMnuItms(List<MlOrdMnuItm> mlOrdMnuItms) {
this.mlOrdMnuItms = mlOrdMnuItms;
}
public MlOrdMnuItm addMlOrdMnuItm(MlOrdMnuItm mlOrdMnuItm) {
getMlOrdMnuItms().add(mlOrdMnuItm);
mlOrdMnuItm.setMlMenuItem(
this);
return mlOrdMnuItm;
}
public MlOrdMnuItm removeMlOrdMnuItm(MlOrdMnuItm mlOrdMnuItm) {
getMlOrdMnuItms().remove(mlOrdMnuItm);
mlOrdMnuItm.setMlMenuItem(
null);
return mlOrdMnuItm;
}
}

第二實體:

@Entity
@Table
(name="ML_FOOD_ITEM")
@NamedQuery
(name="MlFoodItem.findAll", query="SELECT m FROM MlFoodItem m")
public class MlFoodItem implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="FOOD_ITEM_NBR", unique=true, nullable=false)
private short foodItemNbr;
@Column(name="COMPLETED_IND", nullable=false, length=1)
private String completedInd;
@Column(name="FOOD_ITEM_NAME", nullable=false, length=30)
private String foodItemName;
@Column(name="PURCHASED_IND", nullable=false, length=1)
private String purchasedInd;
@ManyToOne
@JoinColumn(name="UNIT_MEASURE_CD", nullable=false)
private MlUnitOfMeasure mlUnitOfMeasure;
@OneToMany(mappedBy="mlFoodItem1", fetch=FetchType.EAGER)
private List<MlFoodItemIngr> mlFoodItemIngrs1;
@OneToMany(mappedBy="mlFoodItem2", fetch=FetchType.EAGER)
private List<MlFoodItemIngr> mlFoodItemIngrs2;
@OneToMany(mappedBy="mlFoodItem", fetch=FetchType.EAGER)
private List<MlMenuFoodItem> mlMenuFoodItems;
public MlFoodItem() {
}
public short getFoodItemNbr() {
return this.foodItemNbr;
}
public void setFoodItemNbr(short foodItemNbr) {
this.foodItemNbr = foodItemNbr;
}
public String getCompletedInd() {
return this.completedInd;
}
public void setCompletedInd(String completedInd) {
this.completedInd = completedInd;
}
public String getFoodItemName() {
return this.foodItemName;
}
public void setFoodItemName(String foodItemName) {
this.foodItemName = foodItemName;
}
public String getPurchasedInd() {
return this.purchasedInd;
}
public void setPurchasedInd(String purchasedInd) {
this.purchasedInd = purchasedInd;
}
public MlUnitOfMeasure getMlUnitOfMeasure() {
return this.mlUnitOfMeasure;
}
public void setMlUnitOfMeasure(MlUnitOfMeasure mlUnitOfMeasure) {
this.mlUnitOfMeasure = mlUnitOfMeasure;
}
public List<MlFoodItemIngr> getMlFoodItemIngrs1() {
return this.mlFoodItemIngrs1;
}
public void setMlFoodItemIngrs1(List<MlFoodItemIngr> mlFoodItemIngrs1) {
this.mlFoodItemIngrs1 = mlFoodItemIngrs1;
}
public MlFoodItemIngr addMlFoodItemIngrs1(MlFoodItemIngr mlFoodItemIngrs1) {
getMlFoodItemIngrs1().add(mlFoodItemIngrs1);
mlFoodItemIngrs1.setMlFoodItem1(
this);
return mlFoodItemIngrs1;
}
public MlFoodItemIngr removeMlFoodItemIngrs1(MlFoodItemIngr mlFoodItemIngrs1) {
getMlFoodItemIngrs1().remove(mlFoodItemIngrs1);
mlFoodItemIngrs1.setMlFoodItem1(
null);
return mlFoodItemIngrs1;
}
public List<MlFoodItemIngr> getMlFoodItemIngrs2() {
return this.mlFoodItemIngrs2;
}
public void setMlFoodItemIngrs2(List<MlFoodItemIngr> mlFoodItemIngrs2) {
this.mlFoodItemIngrs2 = mlFoodItemIngrs2;
}
public MlFoodItemIngr addMlFoodItemIngrs2(MlFoodItemIngr mlFoodItemIngrs2) {
getMlFoodItemIngrs2().add(mlFoodItemIngrs2);
mlFoodItemIngrs2.setMlFoodItem2(
this);
return mlFoodItemIngrs2;
}
public MlFoodItemIngr removeMlFoodItemIngrs2(MlFoodItemIngr mlFoodItemIngrs2) {
getMlFoodItemIngrs2().remove(mlFoodItemIngrs2);
mlFoodItemIngrs2.setMlFoodItem2(
null);
return mlFoodItemIngrs2;
}
public List<MlMenuFoodItem> getMlMenuFoodItems() {
return this.mlMenuFoodItems;
}
public void setMlMenuFoodItems(List<MlMenuFoodItem> mlMenuFoodItems) {
this.mlMenuFoodItems = mlMenuFoodItems;
}
public MlMenuFoodItem addMlMenuFoodItem(MlMenuFoodItem mlMenuFoodItem) {
getMlMenuFoodItems().add(mlMenuFoodItem);
mlMenuFoodItem.setMlFoodItem(
this);
return mlMenuFoodItem;
}
public MlMenuFoodItem removeMlMenuFoodItem(MlMenuFoodItem mlMenuFoodItem) {
getMlMenuFoodItems().remove(mlMenuFoodItem);
mlMenuFoodItem.setMlFoodItem(
null);
return mlMenuFoodItem;
}
}

連接表實體:

@Entity
@Table
(name="ML_MENU_FOOD_ITEM")
@NamedQuery
(name="MlMenuFoodItem.findAll", query="SELECT m FROM MlMenuFoodItem m")
public class MlMenuFoodItem implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private MlMenuFoodItemPK id;
@Column(name="MENU_QUANTITY_NBR", nullable=false, length=4)
private String menuQuantityNbr;
@ManyToOne
@JoinColumn(name="FOOD_ITEM_NBR", nullable=false, insertable=false, updatable=false)
private MlFoodItem mlFoodItem;
@ManyToOne
@JoinColumn(name="MENU_ITEM_NBR", nullable=false, insertable=false, updatable=false)
private MlMenuItem mlMenuItem;
public MlMenuFoodItem() {
}
public MlMenuFoodItemPK getId() {
return this.id;
}
public void setId(MlMenuFoodItemPK id) {
this.id = id;
}
public String getMenuQuantityNbr() {
return this.menuQuantityNbr;
}
public void setMenuQuantityNbr(String menuQuantityNbr) {
this.menuQuantityNbr = menuQuantityNbr;
}
public MlFoodItem getMlFoodItem() {
return this.mlFoodItem;
}
public void setMlFoodItem(MlFoodItem mlFoodItem) {
this.mlFoodItem = mlFoodItem;
}
public MlMenuItem getMlMenuItem() {
return this.mlMenuItem;
}
public void setMlMenuItem(MlMenuItem mlMenuItem) {
this.mlMenuItem = mlMenuItem;
}
}

適用於OpenJPA / Spring數據的Java Config:

@Configuration
@EnableJpaRepositories
public
class JpaConfiguration {
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = 
new DriverManagerDataSource();
dataSource.setUrl(
"jdbc:db2://XXXXXXXX:99999/DATABASENAME");
dataSource.setUsername(
"XXXXXXX");
dataSource.setPassword(
"XXXXXXX");
dataSource.setDriverClassName(
"com.ibm.db2.jcc.DB2Driver");
return dataSource;
}
@Bean
public Map<String, Object> jpaProperties() {
Map<String, Object> props = 
new HashMap<String, Object>();
props.put(
"openjpa.RuntimeUnenhancedClasses", "supported");
props.put(
"openjpa.Log", "Runtime=TRACE, SQL=TRACE, MetaData=TRACE, Enhance=TRACE, DefaultLevel=TRACE");
props.put(
"openjpa.ConnectionFactoryProperties", "PrettyPrint=true, PrettyPrintLineLength=72");
props.put(
"openjpa.jdbc.Schema", "XXXXX");
props.put(
"openjpa.DynamicEnhancementAgent", "false");
props.put(
"openjpa.jdbc.DBDictionary", "db2");
return props;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
OpenJpaVendorAdapter openJpaVendorAdapter = 
new OpenJpaVendorAdapter();
openJpaVendorAdapter.setShowSql(
true);
openJpaVendorAdapter.setGenerateDdl(
true);
openJpaVendorAdapter.setDatabase(Database.
DB2);
return openJpaVendorAdapter;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager(
entityManagerFactory().getObject());
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lef = 
new LocalContainerEntityManagerFactoryBean();
lef.setDataSource(
this.dataSource());
lef.setJpaPropertyMap(
this.jpaProperties());
lef.setJpaVendorAdapter(
this.jpaVendorAdapter());
lef.setPackagesToScan(
this.getClass().getPackage().getName());
return lef;
}

我通過轉儲openJPA並切換到Hibernate解決了該問題。 不確定OpenJPA的實現是否存在問題,但是Hibernate似乎工作得更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM