0

@OneToMany双方向で、のEntityMangerコレクションを持つ ProjectValue を更新するとTask、 メモリ内のプログラムによって削除されるEntityManger子を削除できません。他の機能を使ってそれをTask削除しますか?Task

DataStructure : 

    In ProjectPlan Table :
        PRPJ0001, First Poject
    In Task Table :
        AAA, AAA, PRPJ0001
        BBB, BBB, PRPJ0001
        CCC, CCC, PRPJ0001
    In Memory :
        PRPJ0001, First Poject
            AAA, AAA, PRPJ0001          -->  No Changes
            BBB, Change Name, PRPJ0001  -->  Need to update
                                        -->  Need to delete CCC
            NEW, NEW, PRPJ0001          -->  Need to add 

    Problem : Entity Manger cannot delete CCC;

    @Entity
    public class ProjectPlan {
        @Id
        private String id;
        private String name;
        @OneToMany(mappedBy = "projectPlan", targetEntity = Task.class, cascade = {CascadeType.ALL})
        private List<Task> taskList;

        public ProjectPlan(){}

        public ProjectPlan(String id, String name, List<Task> taskList) {
            this.id = id;
            this.name = name;
            this.taskList = taskList;
        }
        //getter & setter
    }

    @Entity
    public class Task {
        @Id
        private String id;
        private String name;
        @ManyToOne(targetEntity = ProjectPlan.class, cascade = {CascadeType.REFRESH})
        @JoinColumn(name = "projectId", referencedColumnName = "ID")
        private ProjectPlan projectPlan;

        public Task(){
        }

        public Task(String id, String name, ProjectPlan projPlan) {
            this.id = id;
            this.name = name;
            this.projectPlan = projPlan;
        }
        // getter & setter
    }

    public class Test {
        public static void main(String[] args) {
            EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPA");
            EntityManager em = emf.createEntityManager();
            /*
             Existing Data in Database
                List<Task> taskList = new ArrayList<Task>();
                ProjectPlan plan = new ProjectPlan("PRPJ0001", "First Poject", taskList);
                Task task1 = new Task("AAA","AAA", plan);
                Task task2 = new Task("BBB","BBB", plan);
                Task task3 = new Task("CCC","CCC", plan);
                taskList.add(task1);
                taskList.add(task2);
                taskList.add(task3);
            */

            em.getTransaction().begin();
            List<Task> taskList = new ArrayList<Task>();
            ProjectPlan plan = em.find(ProjectPlan.class, "PRPJ0001");

            /*Task "AAA" no changes*/
            Task task1 = new Task("AAA","AAA", plan);

            /*Task "BBB" updated info*/
            Task task2 = new Task("BBB","Change Name", plan);

            /*Task "CCC" removed*/

            /*Task "NEW" newly created*/
            Task task3 = new Task("NEW","NEW", plan);
            taskList.add(task1);
            taskList.add(task2);
            taskList.add(task3);

            plan.setTaskList(taskList);

            em.merge(plan);
            em.getTransaction().commit();
            em.close();
        }
    }

Task別のSub Task List instance(Recursive Relationship) がある場合も、このTask状況に直面します。実際に削除する必要があるタスクを確認して取得する必要がありますか? JPAこの機能をサポートする必要があると思いますか?

4

2 に答える 2

1

アノテーションOneToManyで属性orphanRemovalを使用します。

説明:

1対1または1対多の関係にあるターゲットエンティティが関係から削除される場合、削除操作をターゲットエンティティにカスケードすることが望ましい場合がよくあります。このようなターゲットエンティティは「孤立」と見なされ、orphanRemoval属性を使用して、孤立したエンティティを削除するように指定できます。

@Entity
public class ProjectPlan {
    @Id
    private String id;
    private String name;
    @OneToMany(mappedBy = "projectPlan", cascade = {CascadeType.ALL}, orphanRemoval=true)   // --> new attribute
    private List<Task> taskList;

    public ProjectPlan(){}

    public ProjectPlan(String id, String name, List<Task> taskList) {
        this.id = id;
        this.name = name;
        this.taskList = taskList;
    }
    //getter & setter
}

@Entity
public class Task {
    @Id
    private String id;
    private String name;
    @ManyToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name = "projectId", referencedColumnName = "ID")
    private ProjectPlan projectPlan;

    public Task(){
    }

    public Task(String id, String name, ProjectPlan projPlan) {
        this.id = id;
        this.name = name;
        this.projectPlan = projPlan;
    }
    // getter & setter
}
于 2012-09-26T14:36:59.773 に答える
0

双方向関連には、所有者側と逆側があります。Hibernate は所有者側を調べて、関連付けが存在するかどうかを確認します。所有者側は、属性を持たない側です。mappedByしたがって、この場合、所有者側はタスクです。

そのため、プロジェクト計画からタスク CCC を切り離す場合は、そのprojectPlanフィールドを null に設定する必要があります。タスク CCC を削除する場合は、 を使用して削除する必要がありますem.remove()

于 2012-09-21T08:06:52.627 に答える