简体   繁体   中英

Hibernate @OneToOne and ConstraintViolationException on one side of relationship

I'm just testing hibernate @OneToOne relation and validation on entities fields. Here is my one side of relation:

@Table(name = "devices")
@Entity
public class Device extends BaseEntity  {

    @ManyToOne
    @JoinColumn(name = "device_type_id")
    private DeviceTypeEntity deviceType;

    @NotBlank
    private String name;

    @NotBlank
    private String serial;

    @OneToOne(mappedBy = "device",cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    @NotNull
    private Connection connection;

    @OneToMany(cascade = CascadeType.ALL,fetch=FetchType.LAZY)
    @JoinColumn(name="device_id")
    private List<DeviceStatus> deviceStatuses = new ArrayList<DeviceStatus>();

    // getters and setters

}

Other side of relation

@Table(name = "connections")
@Entity
public class Connection extends BaseEntity {

    private static final long serialVersionUID = 1L;

    @Column(name="connection_id", nullable = false)
    @NotBlank
    private String connectionId;

    private String hostname;

    @NotBlank
    private String ip;

    @Column(name="remote_port",nullable = false)
    private Integer remotePort;

    @Column(name="connection_time",nullable = false)
    @Type(type = "com.app.hos.persistance.custom.DateTimeUserType")
    private DateTime connectionTime;

    @Column(name="end_connection_time")
    @Type(type = "com.app.hos.persistance.custom.DateTimeUserType")
    private DateTime endConnectionTime;

    @JsonIgnore
    @OneToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="device_id")
    @NotNull
    private Device device;


    // setters and getters
}

If I set null to 'connectionId' field in Connection class and save 'Device' object with that 'Connection' ie

  connection.setDevice(device);
  device.setConnection(connection);
  deviceRepository.save(device);

I am expecting ConstraintViolationException and it is ok for me. But I have noticed there is a device entity inserted into database. Why? I expect that if expception occure the transaction is rollback and there will be no enitity in database at all (no connection and no device inserted into db).

You set nullable = false in Device Entity.

@OneToOne(mappedBy = "device",cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(nullable=false)
@NotNull
private Connection connection;

Although what suggested in the other answer fixes the problem from the application point of view, there is a bigger issue here i believe. When you define constraints on application level you mostly do it because you want to detect problems and violations as soon as possible. In this case you wanted to detect a constraint of not null at application level. But the fact that when this constraint wasn't checked, your application wrote data to the database in a case when it shouldn't have, it means you are missing the constraint on database level. This is important and should be handled with bigger priority.

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