解决方法/摆脱 OneToMany 和 ManyToOne 关系中的多个可写映射?
Posted
技术标签:
【中文标题】解决方法/摆脱 OneToMany 和 ManyToOne 关系中的多个可写映射?【英文标题】:workaround/get rid of multiple writable mappings in OneToMany and ManyToOne relationship? 【发布时间】:2011-06-28 18:42:09 【问题描述】:我一直在尝试解决一个问题,但现在卡住了。 我有 2 个实体类/表 Order 和 OrderItem。 OrderItem 有 1 个 Order,Order 有 1..* OrderItems。
我的 EJB 工作正常,它添加订单、获取其 id 并添加订单项目
Order1 order = addOrder(project, name);
em.flush();
int orderId = order.getOrder();
addOrderItem(orderId, cart);
所以一切正常,订单ID也根据需要插入到订单项目行中。
但现在我想使用许多映射实体执行 JPQL,包括 Order 和 OrderItem。据我所知,要执行查询,我需要先映射我的实体,所以问题出在我的映射中。 这是映射
public class Order1 implements Serializable
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "order_")
private Integer order;
...
@OneToMany(mappedBy="orders",targetEntity=OrderItem.class,
fetch=FetchType.EAGER, cascade = CascadeType.ALL)
private List<OrderItem> orderItems;
...
public class OrderItem implements Serializable
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "order_item")
private Integer orderItem;
@Column(name = "order_" /*, insertable=false, updatable=false*/)
private BigInteger order;
...
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="order_")
private Order1 orders;
...
通过这种映射,我在编译时遇到异常
Exception Description: Multiple writable mappings exist for the field [order_item.order_]. Only one may be defined as writable, all others must be specified read-only.
我用谷歌搜索并发现我必须使 OrderItem 中的订单列不可写。正如您在代码中看到的那样,我已经完成并编译,但是当我在我的应用程序中下订单时,订单 ID 不会插入到 order_item 的订单列中并且为 NULL。但是我不能这样,order_item中必须有订单参考。
我的 JPQL 查询是 createQuery("SELECT o.order FROM OrderItem oi JOIN oi.orders o");
当我使 order_item 表中的 order 列不可插入时,它可以工作,但不能这样。有什么建议?我的映射有什么问题,为什么我不能在 order_item 中插入 order_?
更新关于@toto的回答:
我的实体是由 Netbeans 向导生成的。如果我不在OrderItem
中定义BigInteger order
,那么我无法将order id
插入到我的order_item
表中。
我的 EJB 方法如下:
public Order1 addOrder(BigInteger project, BigInteger name)
Order1 order = new Order1();
...
em.persist(order);
return order;
private void addOrderItem(int orderId, ProjectCart cart)
// convert orderId int to BigInteger
BigInteger oId = new BigInteger(String.valueOf(orderId));
OrderItem orderItem = new OrderItem();
orderItem.setOrder(oId);
....
em.persist(orderItem);
所以这意味着如果我离开OrderItem
@Column(name = "order_")
private BigInteger order1;
我在OrderItem
中的order1
的getter 和setter 将不起作用,我不能在addOrderItem()
方法中使用orderItem.setOrder(oId)
只是因为我的order1
没有在OrderItem
中定义。另一件事是我的数据模型中没有外键,但我认为这不是问题,因为在映射中我设置了连接列。
【问题讨论】:
【参考方案1】:您不得在 OrderItem
内定义名称为 order
的列 BigInteger order
。它将由 JPA 自动(在后台)完成。编译器会报错,因为您正在创建一个已由 JPA 创建的列。
【讨论】:
嗨,我已经在我的帖子中进行了更新。我不能在OrderItem
中忽略order
,因为我不能用我的setter 方法设置到order_item
表中。
@Skyzer 我认为你不应该有 setter 方法,只需将新项目添加到订单的映射列表中:order1.orderItems.add(...)
。看起来您正在将 ORM 与手工数据库管理混合在一起,这只会给您带来一些冲突。尝试坚持纯 ORM。以上是关于解决方法/摆脱 OneToMany 和 ManyToOne 关系中的多个可写映射?的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate @OneToMany 与 mappedBy(父子)关系和缓存问题
级联保存不适用于 Hibernate 4 和 @OneToMany