JPA多对一关系-仅需保存ID [英] JPA many-to-one relation - need to save only Id

查看:350
本文介绍了JPA多对一关系-仅需保存ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个班级:驾驶员和汽车.汽车表在单独的过程中更新.我需要的是在Driver中具有属性,该属性使我可以阅读完整的汽车说明,并仅写入指向现有Car的ID.这是示例:

I have 2 classes: Driver and Car. Cars table updated in separate process. What I need is to have property in Driver that allows me to read full car description and write only Id pointing to existing Car. Here is example:

@Entity(name = "DRIVER")
public class Driver {
... ID and other properties for Driver goes here .....

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "CAR_ID")
    private Car car;

    @JsonView({Views.Full.class})
    public Car getCar() {
      return car;
    }
    @JsonView({Views.Short.class})
    public long getCarId() {
      return car.getId();
    }
    public void setCarId(long carId) {
      this.car = new Car (carId);
    }

}

Car对象只是典型的JPA对象,没有向后引用驱动程序.

Car object is just typical JPA object with no back reference to the Driver.

因此,我试图达到的目标是: 1)我可以使用详细的JSON View阅读完整的汽车描述 2)或者我只能在简短的JsonView中读取汽车的ID 3)最重要的是,在创建新的Driver时,我只想传递汽车的JSON ID. 这样,我在持久化期间不需要对汽车进行不必要的读取,而只需更新ID即可.

So what I was trying to achieve by this is: 1) I can read full Car description using detailed JSON View 2) or I can read only Id of the Car in Short JsonView 3) and most important, when creating new Driver I just want to pass in JSON ID of the car. This way I dont need to do unnesessery reads for the Car during persist but just update Id.

出现以下错误:对象引用了一个未保存的瞬态实例-在刷新之前保存该瞬态实例:com.Driver.car-> com.Car"

Im getting following error: "object references an unsaved transient instance - save the transient instance before flushing : com.Driver.car -> com.Car"

我不想在数据库中更新Car的实例,而只是从Driver引用它.知道如何实现我想要的吗?

I dont want to update instance of the Car in DB but rather just reference to it from Driver. Any idea how to achieve what I want?

谢谢.

更新: 忘了提一下,在创建驱动程序期间我通过的汽车ID是数据库中现有汽车的有效ID.

UPDATE: Forgot to mention that the ID of the Car that I pass during creation of the Driver is valid Id of the existing Car in DB.

推荐答案

该错误消息表示您的对象图中有一个瞬态实例,没有明确持久化.简短回顾一下对象在JPA中可以具有的状态:

That error message means that you have have a transient instance in your object graph that is not explicitly persisted. Short recap of the statuses an object can have in JPA:

  • 瞬态:尚未存储在数据库中的新对象(因此对于实体管理器而言是未知的.)没有设置ID.
  • 托管:实体管理器跟踪的对象.托管对象是您在事务范围内使用的对象,一旦提交事务,对托管对象所做的所有更改将自动存储.
  • 已分离:提交转换后仍可访问的先前管理的对象. (交易之外的托管对象.)设置了ID.
  • Transient: A new object that has not yet been stored in the database (and is thus unknown to the entitymanager.) Does not have an id set.
  • Managed: An object that the entitymanager keeps track of. Managed objects are what you work with within the scope of a transaction, and all changes done to a managed object will automatically be stored once the transaction is commited.
  • Detached: A previously managed object that is still reachable after the transction commits. (A managed object outside a transaction.) Has an id set.

该错误消息告诉您的是,您正在使用的(托管/分离)驱动程序对象持有对Hibernate未知(瞬态)的Car对象的引用.为了使Hibernate理解,也应该保存从Driver引用的要保存的Car的所有未保存实例,也可以保存,您可以调用EntityManager的persist-method.

What the error message is telling you is that the (managed/detached) Driver-object you are working with holds a reference to a Car-object that is unknown to Hibernate (it is transient). In order to make Hibernate understand that any unsaved instances of Car being referenced from a Driver about be saved should also be saved you can call the persist-method of the EntityManager.

或者,您可以在持久性上添加一个层叠(我想,只是从我的头顶上还没有测试过),它将在持久化驱动程序之前在Car上执行持久化.

Alternatively, you can add a cascade on persist (I think, just from the top of my head, haven't tested it), which will execute a persist on the Car prior to persisting the Driver.

@ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
@JoinColumn(name = "CAR_ID")
private Car car;

如果使用entitymanager的合并方法存储驱动程序,则应改为添加CascadeType.MERGE或两者:

If you use the merge-method of the entitymanager to store the Driver, you should add CascadeType.MERGE instead, or both:

@ManyToOne(fetch=FetchType.LAZY, cascade={ CascadeType.PERSIST, CascadeType.MERGE })
@JoinColumn(name = "CAR_ID")
private Car car;

这篇关于JPA多对一关系-仅需保存ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆