关系的一方是Hibernate @OneToOne和ConstraintViolationException

时间:2018-06-14 16:27:16

标签: java spring hibernate

我只是在实体字段上测试hibernate @OneToOne关系和验证。 这是我关系的一面:

@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

}

关系的另一面

@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
}

如果我在Connection类中将null设置为'connectionId'字段并使用'Connection'保存'Device'对象,即

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

我期待ConstraintViolationException,它对我来说没问题。但我注意到有一个设备实体插入数据库。为什么? 我希望如果发生expex,那么事务就会回滚,并且数据库根本没有任何启发(没有连接,没有设备插入到db中)。

2 个答案:

答案 0 :(得分:0)

您在设备实体中设置nullable = false

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

答案 1 :(得分:0)

虽然在其他答案中提出的建议从应用程序的角度来解决问题,但我认为这里有一个更大的问题。在应用程序级别定义约束时,您通常会这样做,因为您希望尽快检测到问题和违规。在这种情况下,您希望在应用程序级别检测not null的约束。但是,当未检查此约束时,您的应用程序在数据库不应该具有的情况下将数据写入数据库,这意味着您缺少数据库级别的约束。这很重要,应该以更高的优先级处理。