简体   繁体   中英

JPA merge parent with new child

I have the following structure (OneToOne unidirectional)

@Entity
public class Car {
    @Id
    @Column(name = ID)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToOne(fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, orphanRemoval = true )
    @JoinColumn(name = "DRIVER_ID")
    private Driver driver;

    // setters and getters and other properties
}

@Entity
public class Driver {
    @Id
    @Column(name = ID)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    // setters and getters and other properties
}

The problem is, that if I already have an existing Car, but no driver and I add a driver to the queried Car from the database, the Driver will get inserted (I see the insert query generated).

The following logic happens inside a transaction:

// this is a raw version of the code that gets executed, skipped validation and stuff like that
public void addDriver(long carId, Driver driver) {
    entityManager.persist(driver);
    Car car = entityManager.find(Car.class, carId);
    car.setDriver(driver);
}

After the transaction is finished, I query the car, but the car doesn't have a driver attached. Any idea why this is happening and how can this be fixed?

If you're relying on your entity existing in the database after your call to persist(), but before the transaction commits, then call flush() first.

Refer this for details:

http://blakecaldwell.net/blog/2013/9/3/dont-rely-on-entitymanagerpersist-for-immediate-insert.html

And if you try

public void addDriver(long carId, Driver driver) {
Car car = entityManager.find(Car.class, carId); car.setDriver(driver); entityManager.merge(car) }

Because you are cascading the car should be inserted and linked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM