【问题标题】:PersistenceException: ERROR executing DML bindLog when Updating an ObjectPersistenceException:更新对象时执行 DML bindLog 时出错
【发布时间】:2014-06-08 07:47:15
【问题描述】:

美好的一天!我有两个对象:TagRelatedTagTag 可以有多个RelatedTags(这也是一个Tag)。保存 Tag 及其相关标签可以正常工作。但是当我更新Tag 时,出现错误提示

[PersistenceException: ERROR executing DML bindLog[] error[Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.RELATED_TAG(ID)"; SQL statement:\n insert into related_tag (id, tag_id, relationship, related_notes) values (?,?,?,?) [23505-172]]]

这里是Tag 模型:

package models;

import java.util.*;

import javax.persistence.*;
import javax.validation.*;

import play.data.Form;
import play.data.validation.Constraints.*;
import play.db.ebean.*;
import play.db.ebean.Model.Finder;
import scala.Int;

@Entity
public class Tag extends Model{

    @Id
    private int id;

    @Required
    @MaxLength(value=100)
    private String name;

    @MaxLength(value=200)
    private String notes;

    @OneToMany(cascade=CascadeType.ALL)
    public List<RelatedTag> relatedTags = new ArrayList<RelatedTag>();

    public static Finder<Integer, Tag> find = new Finder(Int.class, Tag.class);

    public Tag() {

    }

    public Tag(String name, String notes){
        this.name = name;
        this.notes = notes;
    }

    public Tag(int id, String name, String notes, List<RelatedTag> relatedTags) {
        this.id = id;
        this.name = name;
        this.notes = notes;
        this.relatedTags = relatedTags;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNotes() {
        return notes;
    }

    public void setNotes(String notes) {
        this.notes = notes;
    }

    public List<RelatedTag> getRelatedTags() {
        return relatedTags;
    }

    public void setRelatedTags(List<RelatedTag> relatedTags) {
        this.relatedTags = relatedTags;
    }

    public static List<Tag> all() {
        return find.all();
    }

    public static void create(Tag tag){
        tag.save();
    }

    public static void delete(int id){
        find.ref(id).delete();
    }

    public static void update(int id, Tag tag) {
        tag.update(id); // updates this entity, by specifying the entity ID
    }

    public static boolean exists(Tag newTag) {
        for(Tag allTags : Tag.find.all()) {
            if(allTags.getName().equals(newTag.getName()))
                return true;
        }

        return false;
    }       

}

这是RelatedTag 模型:

package models;

import java.util.*;

import javax.persistence.*;
import javax.validation.*;

import play.data.Form;
import play.data.validation.Constraints.*;
import play.db.ebean.*;
import play.db.ebean.Model.Finder;
import scala.Int;

@Entity
public class RelatedTag extends Model {

    @Id
    private int id;

    private String relationship;

    private String relatedNotes;

    public RelatedTag() {}

    public RelatedTag(int id, String relationship, String relatedNotes) {
        this.id = id;
        this.relationship = relationship;
        this.relatedNotes = relatedNotes;
    }

    public void setId(int id){
        this.id = id;
    }

    public void setRelationship(String relationship){
        this.relationship = relationship;
    }

    public void setRelatedNotes(String relatedNotes) {
        this.relatedNotes = relatedNotes;
    }

    public int getId(){
        return id;
    }


    public String getRelationship(){
        return relationship;
    }

    public String getRelatedNotes() {
        return relatedNotes;
    }

    public static boolean exists(String tagRelated) {
        for(Tag tag : Tag.find.all()) {
            if(tagRelated.equals(tag.getName()))
                return true;
        }
        return false;
    }

    public static RelatedTag findByLabel(String tagRelated, String relation, String relatedNotes) {
        RelatedTag relatedTag = null;
        for(Tag tag : Tag.find.all()) {
            if(tagRelated.equals(tag.getName())) {
                relatedTag = new RelatedTag(tag.getId(), relation, relatedNotes);
            }
        }
        return relatedTag;
    }

    public static Tag findTag(int id) {
        for(Tag tag : Tag.find.all()) {
            if(id == tag.getId()) 
                return tag;
        }
        return null;
    }

}

当我运行它时(我在其中更新了Tag),就会发生错误。

private static void reciprocate(Tag tag) {
            List<Tag> peers = new ArrayList<Tag>();

            for (RelatedTag rt : tag.getRelatedTags()) {
                if(rt.getRelationship().equals("peer"))
                    peers.add(RelatedTag.findTag(rt.getId()));
            }

        for(RelatedTag rt : tag.getRelatedTags()) {
            int relTemp = 0;
            String relation = new String();
            if (rt.getRelationship().equals("parent"))
                relTemp = 1; 
            if (rt.getRelationship().equals("child"))
                relTemp = 2; 
            if (rt.getRelationship().equals("peer"))
                relTemp = 3; 
            switch(relTemp) {
                case 1: relation = "child"; break;
                case 2: relation = "parent"; break;
                case 3: relation = "peer"; break;
            }

            Tag related = new Tag();
            related = Tag.find.byId(RelatedTag.findTag(rt.getId()).getId());
            List<RelatedTag> available = new ArrayList<RelatedTag>();
            List<String> availableName = new ArrayList<String>();
            for (RelatedTag rt2 : related.getRelatedTags()) {
                availableName.add(RelatedTag.findTag(rt2.getId()).getName());
            }
            if(availableName.contains(tag.getName())) {
                for(RelatedTag rt2 : related.getRelatedTags()) {
                    if(!RelatedTag.findTag(rt2.getId()).getName().equals(tag.getName())) {
                        available.add(rt2);
                    }
                }
            }
            available.add(RelatedTag.findByLabel(
                    tag.getName(), relation,
                    rt.getRelatedNotes()));
            related.setRelatedTags(available);
            related.update(related.getId());    //HERE          
        }
}

请帮我解决这个问题。在迭代第一个rt 之后,出现错误,但它保存了其相关标签。非常感谢。

【问题讨论】:

  • 我看到两个实体,但实体本身没有编码关系。
  • 对不起,你说的关系是什么意思?谢谢。
  • 啊,抱歉,您的 OneToMany 关系是单向的,从标签到相关标签;此外,您的 reciprocate 方法似乎过于复杂。
  • 谢谢。我在RelatedTag 中添加了一个字段public Tag tag;,并带有注释@ManyToOne。我将relatedTags 的注释更改为@OneToMany(mappedBy="tag", cascade=CascadeType.ALL),但它仍然无法正常工作。至于reciprocate,我确实需要这样做。而且,即使在标签名称的简单更新中也会发生错误,因此update 确实会导致这种情况。
  • 整个relation if/switch 在代码的开头?不做任何事情,从不使用该值,相当于String relation = rt.getRelationship()

标签: sql database jpa ebean


【解决方案1】:

您的方法RelatedTag#findByLabel 总是使用 Tag 类的 ID 创建新的 RelatedTags;如果同一个标签有 2 个相关标签,它将产生 2 个具有相同 ID 的相关标签。

查看@GeneratedValueEntityManager#createQuery

【讨论】:

  • 谢谢!但我正在reciprocate 方法中检查标签名称的唯一性。在添加最新的之前,我首先“删除”与标签同名的相关标签。 if(!RelatedTag.findTag(rt2.getId()).getName().equals(tag.getName())) { available.add(rt2); }
  • 当我将related.setRelatedTags(available); 更改为related.getRelatedTags().clear(); 时,也不例外。这意味着问题在于设置新的相关标签集。我先尝试了related.getRelatedTags().clear();,然后尝试了related.setRelatedTags(available);,但错误仍然存​​在。我真的需要你的帮助,先生。请,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-26
  • 1970-01-01
  • 2017-07-03
  • 1970-01-01
  • 2020-07-23
相关资源
最近更新 更多