PersistenceException: ERROR executing DML bindLog when Updating an Object

﹥>﹥吖頭↗ 提交于 2019-12-14 04:06:08

问题


Good day! I have two objects: Tag and RelatedTag. The Tag can have many RelatedTags (which is also a Tag). Saving the Tag with its related tags works fine. But when I update the Tag, it has an error saying

[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]]]

Here is Tag model:

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;
    }       

}

And here is the RelatedTag model:

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;
    }

}

When I run this (in which I update a Tag), the error happens.

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          
        }
}

Please help me figure this out. After the first rt has been iterated, there goes the error but it saves its related tag. Thank you very much.


回答1:


Your method RelatedTag#findByLabel always creates new RelatedTags with the IDs of the Tag class; if you have 2 related tags for the same tag, it will produce 2 related tags with the same ID.

Look into @GeneratedValue and EntityManager#createQuery.



来源:https://stackoverflow.com/questions/24104056/persistenceexception-error-executing-dml-bindlog-when-updating-an-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!