简体   繁体   中英

hibernate merge throws EntityNotFoundException

I have a Hibernate entity class representing a "device" table, which is linked to N deviceNetworks:

@Entity
    @Configurable  
    @Table(name = "device")
    public class Device implements Serializable
    {
        private static final long serialVersionUID = 1L;

        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private long id;


        @Column(name = "device_name", nullable = false)
        private String deviceName;


        @OneToMany( cascade = {CascadeType.ALL}, fetch = FetchType.LAZY, 
                    mappedBy = "device_network", 
                    targetEntity = DeviceNetwork.class, orphanRemoval = true)
        private final Set<DeviceNetwork> deviceNetworks = Sets.newHashSet();

        ......

        public Set<DeviceNetwork> getDeviceNetworks()
        {
            return deviceNetworks;
        }

        public void addDeviceNetwork(final DeviceNetwork deviceNetwork)
        {
            deviceNetworks.add(deviceNetwork);
        }

        public void removeDeviceNetwork(final DeviceNetwork deviceNetwork)
        {
            deviceNetworks.remove(deviceNetwork);
        }
    }

and the class representing "deviceNetwork":

@Entity
@Configurable
@Table(name = "device_network")
public class DeviceNetwork implements Serializable
{
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @ManyToOne(targetEntity = Device.class)
    @JoinColumn(name="device_id", nullable=false)
    private Device device;
    @Column(name = "network_name", unique = true, nullable = false)
    private String networkName;
    ......
}

I have a transaction that inserted a new device and a new linked deviceNetwork into DB, then I started with a new tranaction:

  1. retrieve the newly inserted device by its id;
  2. add a new network;
  3. update the device;

I use EntityManager to accomplish this:

@Transactional
public void addNetworkToDevice(long deviceId, DeviceNetwork deviceNetwork)
{
    Device device = entityManager.get(deviceId); 

    device.addDeviceNetwork(deviceNetwork);

    entityManager.merge(device);
}

This causes the following exceptions:

org.springframework.orm.jpa.JpaObjectRetrievalFailureException: 
Unable to find com.xxx.domain.DeviceNetwork with id 170; 
nested exception is javax.persistence.EntityNotFoundException: 
Unable to find com.xxx.domain.DeviceNetwork with id 170

The id=170 is supposed to be the DeviceNetwork to be inserted. It appears that the merge() would try to retrieve the about-to-inserted deviceNetwork by its auto-generated id, but failed to do so because it hasn't been inserted.

An interesting thing is that if I insert a new device and 2 new linked deviceNetworks in the same transaction, it works fine:

@Transactional
public void addDevice(Device device, DeviceNetwork deviceNetwork1, DeviceNetwork deviceNetwork2)
{
    Device deviceInDB = entityManager.get(device.getDeviceId());
    if deviceInDB == null)
    {
        entityManager.persist(device);
        deviceInDB = entityManager.get(device.getDeviceId());
    }

    deviceInDB.addDeviceNetwork(deviceNetwork1);
    deviceInDB.addDeviceNetwork(deviceNetwork2);

    entityManager.merge(deviceInDB);
}

Any suggestions?

检查项目中提到的数据库用户是否有权访问表device_network

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