我只是在实体字段上测试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中)。
答案 0 :(得分:0)
您在设备实体中设置nullable = false
。
@OneToOne(mappedBy = "device",cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(nullable=false)
@NotNull
private Connection connection;
答案 1 :(得分:0)
虽然在其他答案中提出的建议从应用程序的角度来解决问题,但我认为这里有一个更大的问题。在应用程序级别定义约束时,您通常会这样做,因为您希望尽快检测到问题和违规。在这种情况下,您希望在应用程序级别检测not null
的约束。但是,当未检查此约束时,您的应用程序在数据库不应该具有的情况下将数据写入数据库,这意味着您缺少数据库级别的约束。这很重要,应该以更高的优先级处理。