我一直试图用Play Framework 2.5学习Ebean几天。我可以做我想做的一切,除了删除一个实体(我不想使用sql,除非有必要)。
每次我尝试删除商品(myoffer.delete()
)时,都会抛出此异常:
[RuntimeException: get author on [model.Offer] type[null] threw error.]
优惠类是:
@Entity
public class Offer extends Model {
//Basic Fields
@Id
public Long id;
@Constraints.Required
@Column(nullable = false)
public String title;
@Constraints.Required
@Column(nullable = false)
public String description;
@Column(nullable = false)
public Date publishDate;
public Date startDate;
public Date finishDate;
@Column(nullable = false)
public boolean sold;
//Relations
@JoinColumn(nullable = false)
@ManyToOne(cascade = CascadeType.ALL)
public User author;
@JoinColumn(nullable = false)
@ManyToOne(cascade = CascadeType.ALL)
public OfferCategory category;
@ManyToMany(cascade = CascadeType.ALL, mappedBy="offers")
public List<Image> images;
//Finder
public static Finder<Long, Offer> find = new Finder<>(Offer.class);
@PreRemove
protected void preRemove() {
for(Image img:this.images){
img.offers.remove(this);
}
this.author.offers.remove(this);
}
//Constructors
public Offer(){}
}
我在这里做错了什么?
在这种情况下,由于删除方法的使用非常少,我使用的是纯SQL查询。我知道方法性能可能不是最好的,但至少它起作用了:
@Override
public void delete(Long... idsLongArray) {
StringBuilder deleteImages = new StringBuilder("DELETE FROM image_offer WHERE offer_id IN (?)");
StringBuilder deleteOffer = new StringBuilder("DELETE FROM offer WHERE id IN (?)");
int j;
int k;
for (int i = 1; i < idsLongArray.length; i++) {
j = deleteImages.lastIndexOf("?");
k = deleteOffer.lastIndexOf("?");
deleteImages.replace(j, j + 1, "?,?");
deleteOffer.replace(k, k + 1, "?,?");
}
SqlUpdate imgQuery = Ebean.createSqlUpdate(deleteImages.toString());
SqlUpdate offerQuery = Ebean.createSqlUpdate(deleteOffer.toString());
for (int i = 0; i < idsLongArray.length; i++) {
imgQuery.setParameter(i + 1, idsLongArray[i]);
offerQuery.setParameter(i + 1, idsLongArray[i]);
}
imgQuery.execute();
offerQuery.execute();
/*List<Offer> offers = Offer.find.select("id").where().in("id", idsLongArray).findList();
for(Offer offer: offers){
offer.save();
offer.delete();
}*/
}
使用@Salem在评论中告诉我的建议,我们使其成功。我只需要从多对一关系中移除cascade=CascadeType.ALL
参数。
@JoinColumn(nullable = false)
@ManyToOne
public User author;
@JoinColumn(nullable = false)
@ManyToOne
public OfferCategory category;
我的最终删除方法如下所示:
public void delete(Long... idsLongArray) {
for(Long id: idsLongArray){
Offer.find.byId(id).delete();
}
}