如何解决持久保存实体对象,其中外键是复合主键Spring Boot,Spring JPA的一部分-引发错误
@Entity
@Table(name = "pharmacy",schema = "master_relational_db")
public class Pharmacy {
@Id @Column(name = "id_pharmacy",columnDeFinition = "INT(3)") private Integer id;
... some other columns
@OnetoMany(mappedBy = "pharmacy",cascade = CascadeType.ALL,fetch = FetchType.LAZY)
private List<Article> articles;
以上类别代表药房,并且具有简单的整数ID。
@Entity
@Table(name = "article",schema = "master_relational_db")
public class Article {
@EmbeddedId private ArticleId id;
@Column(name ="name",length = 512,nullable = false) private String name;
... some other columns
@MapsId("id_article_pharmacy")
@ManyToOne(cascade = {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH},fetch = FetchType.LAZY)
@JoinColumn(name ="article_pharmacy_fk")
private Pharmacy pharmacy;
上述类是代表属于特定药房的商品的类。它与药房有@ManyToOne关系,并且外键也是文章的嵌入式(ArticleId)主键的一部分。
@Embeddable
public class ArticleId implements Serializable {
@Column(name = "id_article")
private Integer idArticle;
@Column(name = "id_article_pharmacy")
private Integer idPharmacy; //this is filled with foreign key (this is id of linked pharmacy)
public ArticleId(Integer idArticle,Integer idPharmacy){
this.idArticle = idArticle;
this.idPharmacy = idPharmacy;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ArticleId)) return false;
ArticleId that = (ArticleId) obj;
return Objects.equals(getIdPharmacy(),that.getIdPharmacy()) &&
Objects.equals(getIdArticle(),that.getIdArticle());
}
@Override
public int hashCode() {
return Objects.hash(getIdArticle(),getIdPharmacy());
}
}
以上类代表商品的ID,它具有一些整数商品ID(id_article)和药房ID,这也是表示ManyToOne与药房关系的外键。 我运行上面的代码,并根据需要在数据库中创建表。我用一些数据填充了药房表格,但是当我要创建新文章并将其与某些药房问题链接时,就会出现。下是用于添加新文章的代码,此代码是我用于添加新文章的服务(@Service)方法的一部分:
@Transactional
public void addArticle() throws sqlException {
Article toSave = new Article(...constructor for setting fields that are not pk or fk);
Pharmacy ap = pharmacyRepository.findById(idOfPharmacy).get(); //we get pharmacy //with some id that we want to link this new article with.
//I debug this code and findById returns wanted pharmacy from DB.
ArticleId id = new ArticleId(10,ap.getId());//we create ArticleId with id_article = 10 and id_article_pharmacy = (id of ap object (id of pharmacy that we get from findById method))
toSave.setId(id);//we set id for article
toSave.setPharmacy(ap);//we set pharmacy for article (foreign key - should be same as id_article_pharmacy from AricleId)
System.out.println("ID [Id of pharmacy is: " +toSave.getId().getIdPharmacy() + " | id of article is : "
+toSave.getId().getIdArticle() + "] fk pharmacy name is: " + toSave.getPharmacy().getName()); // this is what i get here when i run it : ID [Id of pharmacy is: 1 | id of article is : 1] fk pharmacy name is: Pharmacy BENU - so all data is linked
//ap.addArticle(toSave);
articleRepository.save(toSave); //we use repository that extends CrudRepository to save article in db.
}
当我使用此服务时,出现此错误:java.sql.sqlException:字段“ article_pharmacy_fk”没有默认值 在com.MysqL.cj.jdbc.exceptions.sqlError.createsqlException(sqlError.java:129)〜[mysql-connector-java-8.0.21.jar:8.0.21] 在com.MysqL.cj.jdbc.exceptions.sqlError.createsqlException(sqlError.java:97)〜[mysql-connector-java-8.0.21.jar:8.0.21] ......等等 有人可以帮我我尝试过一切吗? :/
..解决方案.... 问题出在我的ArticleId的定义中。我不需要为idPharmacy定义@Column antotation(因为我不想为此创建新列,我想引用它)。所以我删除了@Column注释。我还需要用@MapsId(“ idPharmacy”)替换@MapsId(“ id_article_pharmacy”)。这就是我解决问题的方式。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。