【发布时间】:2020-11-06 12:23:51
【问题描述】:
我正在使用 @OneToMany 和 @ManyToOne 注释进行单向和双向映射,但在持久化实体并将它们刷新到数据库时,我无法打破单向映射的障碍。
所以,两个表delivery_company 可能有很多delivery:
SQL(甲骨文):
CREATE TABLE delivery (
delivery_id NUMBER(6) NOT NULL,
price NUMBER(5, 2) NOT NULL,
delivery_time DATE NOT NULL,
delivery_company_id NUMBER(2) NOT NULL
);
ALTER TABLE delivery ADD CONSTRAINT delivery_pk PRIMARY KEY ( delivery_id );
CREATE TABLE delivery_company (
delivery_company_id NUMBER(2) NOT NULL,
delivery_company_name VARCHAR2(15 CHAR) NOT NULL
);
ALTER TABLE delivery_company ADD CONSTRAINT delivery_company_pk PRIMARY KEY ( delivery_company_id );
ALTER TABLE delivery
ADD CONSTRAINT delivery_delivery_company_fk FOREIGN KEY ( delivery_company_id )
REFERENCES delivery_company ( delivery_company_id );
单向映射:
@Entity
@Table(name = "Delivery")
class DeliveryUniDirectional
{
@Id
@SequenceGenerator(name = "delivery_id_sequence", sequenceName = "delivery_id_sequence", allocationSize = 1)
@GeneratedValue(generator = "delivery_id_sequence", strategy = GenerationType.SEQUENCE)
@Column(name = "delivery_id")
public Long deliveryId;
public BigDecimal price;
@Temporal(TemporalType.DATE)
public Date deliveryTime;
// setters, getters
}
@Entity
@Table(name = "delivery_company")
class DeliveryCompanyUniDirectional {
@Id
@Column(name = "delivery_company_id")
@SequenceGenerator(name = "delivery_company_id_sequence", sequenceName = "delivery_company_id_sequence", allocationSize = 1)
@GeneratedValue(generator = "delivery_company_id_sequence", strategy = GenerationType.SEQUENCE)
private Long deliveryCompanyId;
@Column(unique = true)
private String deliveryCompanyName;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "delivery_id", nullable = false, insertable = false, updatable = false)
private List<DeliveryUniDirectional> deliveries = new LinkedList<>();
// setters getters
}
当我运行@DataJpaTest 测试时:
@Test
public void insertDeliveryUniDirectional()
{
DeliveryCompanyUniDirectional deliveryCompany = new DeliveryCompanyUniDirectional();
deliveryCompany.setDeliveryCompanyName("aa");
DeliveryUniDirectional delivery = new DeliveryUniDirectional();
delivery.setPrice(BigDecimal.ONE);
delivery.setDeliveryTime(new Date());
deliveryCompany.getDeliveries().add(delivery);
entityManager.persist(deliveryCompany);
entityManager.flush();
}
我收到
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute batch ...
//
Caused by: java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("TESTUSER"."DELIVERY"."DELIVERY_COMPANY_ID")
当entityManager.flush();.
我尝试在 DeliveryCompanyUniDirectional 中使用 @JoinColumn 而不可插入和更新,但在这种情况下 hibernate 抱怨:
Error creating bean with name 'entityManagerFactory' defined in class path resource ...
// ...
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: wieczorek.jakub.shop.business.spring.model.domain.DeliveryUniDirectional column: delivery_id (should be mapped with insert="false" update="false")
delivery 表中外键的NOT NULL 约束肯定有问题。当我尝试使用双向映射时,持久化和刷新效果非常好,但我想使用单向实现同样的效果。
感谢阅读
【问题讨论】:
标签: java sql oracle spring-boot hibernate