简体   繁体   English

JPA将实体的“多对多”字段值替换为其他值

[英]JPA replacing Many to Many field value of an Entity to a different value

I have an Entity called Artwork which has a member called subjects mapped Many to Many with another entity as follows. 我有一个称为Artwork的实体,该实体有一个名为Artwork的成员,它与另一个实体的映射关系如下。

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<ArtSubject> subjects;

Assume that in my Artwork table i have a record with subjects values as (ArtSubject1, ArtSubject2, ArtSubject3) 假设在我的Artwork表中,我有一条记录,其主题值为(ArtSubject1, ArtSubject2, ArtSubject3)

I have to replace this value with (ArtSubject5, ArtSubject6, ArtSubject7) . 我必须用(ArtSubject5, ArtSubject6, ArtSubject7)替换此值。

Completely different List. 完全不同的列表。

Curretly if i save an Artwork object with new data as (ArtSubject5, ArtSUbject6, ArtSubject7) . 如果我将带有新数据的Artwork对象保存为(ArtSubject5, ArtSUbject6, ArtSubject7)

JPA appends it with the already existing list and the resulting data is (ArtSubject1, ArtSubject2, ArtSubject3, ArtSubject5, ArtSUbject6, ArtSubject7) JPA将其附加到已经存在的列表中,并且结果数据为(ArtSubject1, ArtSubject2, ArtSubject3, ArtSubject5, ArtSUbject6, ArtSubject7)

I want it to be only (ArtSubject5, ArtSubject6, ArtSubject7) 我只希望它是(ArtSubject5, ArtSubject6, ArtSubject7)

Please find the method where i save the ArtSubject and set it to the Artwork object. 请找到我保存ArtSubject并将其设置为Artwork对象的方法。

ArtWork artwork = new ArtWork();
        List<ArtSubject> subject = new ArrayList<>();
        List<ArtStyle> style = new ArrayList<>();
        Artist artist = new Artist();
        List<ArtCollection> artCollections = new ArrayList<>();

        // Classifying Collections into each category.
        for (Collection collection : collections) {
            String tokens[] = collection.getTitle().split("_");
            if (tokens == null || tokens.length < 2) {
                LOGGER.info("Invalid Collection Type: Collection type {} not recognised", 
                        collection.getTitle());
                continue;
            }
            String collectionType = tokens[0]; 
            switch(collectionType) {
            case "subject":
                ArtSubject artSubject = new ArtSubject(collection.getId(), 
                        collection.getTitle().split("_")[1]);
                subject.add(artSubject);
                artSubjectRepository.save(artSubject);
                break;
            default:
                LOGGER.info("Invalid Collection Type: Collection type {} not recognised", 
                        collection.getTitle());
                break;
            }
        }


        artwork.setSubject(subject);

After this i save the artwork as artRepository(CRUD Repository) artRepository.save(artwork) Please help me with this. 在此之后,我将艺术品另存为artRepository(CRUD存储库) artRepository.save(artwork)请帮助我。

Thanks in advance! 提前致谢!

Try below approaches 尝试以下方法

For Collection(List) ( artwork.setSubjects(new ArrayList<Subject>()); ) you have to clear() the existing one. 对于Collection(List)artwork.setSubjects(new ArrayList<Subject>()); ),您必须clear()现有的。 This happens because if Hibernate loads the entity (and its collections) from DB, it "manages" them, ie. 发生这种情况是因为,如果Hibernate从DB加载了实体(及其集合),它将“管理”它们。 tracks their changes. 跟踪他们的更改。 Generally when using Hibernate it's better not to create any setters for collections (lists, sets) . 通常,在使用Hibernate时,最好不要setters for collections (lists, sets)创建任何setters for collections (lists, sets) Create only the getter, and clear the collection returned by it, ie: 仅创建吸气剂,并清除其返回的集合,即:

artwork.getSubject().clear();

Also, use orphan deletion (ie. delete child object when it's removed from collection in the parent). 另外,请使用orphan deletion (即,从子对象的集合中删除子对象时删除子对象)。 Add @OneToMany(orphanRemoval=true) in owning entity. 在拥有实体中添加@OneToMany(orphanRemoval=true)

Try this, I am trying to save a person which has oneToMany relationship too...I just use saveOrUpdate, and in frontend even if person edits his details, I call the same method : 试试这个,我也试图保存一个具有oneToMany关系的人...我只是使用saveOrUpdate,并且在前端,即使该人编辑了他的详细信息,我也会调用相同的方法:

@Override
    @Transactional
    public void addPerson(Person p) {

        if( session == null) {
            session = this.sessionFactory.openSession();
        }else {
            session = this.sessionFactory.getCurrentSession();
        }
        session.saveOrUpdate(p);
        session.flush();

    }

For saving the entity mapped with one-to-many, i do it this way : here alsso, if canvas details are changed, it does not matter, I call the same method. 为了保存一对多映射的实体,我这样做:在这里也可以更改画布的详细信息,这没关系,我调用相同的方法。

@Override
public void addCanvas(Canvas canvas, Person person) {
    int id = person.getId();
    if( session == null) {
        session = this.sessionFactory.openSession();
    }else {
        session = this.sessionFactory.getCurrentSession();
    }
    Person person1 = (Person) session.get(Person.class,id);
    person.getCanvas1().add(canvas);
    canvas.setPerson1(person1);
   session.merge(canvas);

    session.flush();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM