Java 如何使用em.merge()更新实体引用的列表

Java 如何使用em.merge()更新实体引用的列表,java,google-app-engine,jpa-2.0,Java,Google App Engine,Jpa 2.0,我正在尝试更新指向列表的实体(EntityObjectContainigList)。我从数据库中获取实体,分离它,从实体指向的列表中删除一些元素,然后尝试将更新的实体与驻留在数据库中的实体合并 现在的问题是,当我运行em.merge(EntityObjectContainigList)时,列表引用的对象/实体(我删除的对象)仍然保留在DB中。 servlet如下所示: @Entity public class ContainerObject { @Id @Generate

我正在尝试更新指向列表的实体(EntityObjectContainigList)。我从数据库中获取实体,分离它,从实体指向的列表中删除一些元素,然后尝试将更新的实体与驻留在数据库中的实体合并

现在的问题是,当我运行em.merge(EntityObjectContainigList)时,列表引用的对象/实体(我删除的对象)仍然保留在DB中。

servlet如下所示:

@Entity
public class ContainerObject {

     @Id
     @GeneratedValue(strategy=GenerationType.IDENTITY)
     @JsonIgnore
     private Key id;

    @ManyToOne(fetch = FetchType.LAZY)
    EntityObjectContainigList eocl;


    private String s;

    private int i;


    public String getS() {
            return s;
    }

    public void setS(String s) {
        this.s = s;
    }

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }


}
@Path("/db")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class MyResourcse {

    private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("transactions-optional");

    @PUT
    public Response putInDb(EntityObjectContainigList d) {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();
/*          Gson g = new Gson();
            System.out.println(g.toJson(d));*/
            em.persist(d);
            return Response.ok().build();
        } finally {
            if (em != null && em.isOpen()) em.close();
        }
    }

    @GET
    public Response getFromDb(@QueryParam("id")Long id) {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();
/*          Gson g = new Gson();*/
            EntityObjectContainigList o = em.find(EntityObjectContainigList.class, id);
/*          System.out.println(g.toJson(o));*/
            return Response.ok(o).build();
        } finally {
            if (em != null && em.isOpen()) em.close();
        }
    }

    @POST
    public Response updateDb(EntityObjectContainigList d) {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();
            Gson g = new Gson();
            d =  em.merge(d);
            System.out.println(g.toJson(d));
            return Response.ok().build();
        } finally {
            if (em != null && em.isOpen()) em.close();
        }
    }
}
public class UpdateClient {

    public static void main(String[] args) {
        ClientConfig cc = new DefaultClientConfig();
        cc.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);

        Client client = Client.create(cc);

        WebResource res = client.resource("http://localhost:8888/rest/db");


        EntityObjectContainigList o = new EntityObjectContainigList();
        o.setId(12L);
        o.setName("hello");

        for (int i = 0; i < 5; i++) {
            ContainerObject c = new ContainerObject();
            c.setI(i);
            c.setS("foo" + i );
            o.getList().add(c);
        }


        res.type(MediaType.APPLICATION_JSON).put(ClientResponse.class, o);

        System.out.println("Object inserted");

        o = res.queryParam("id", "12")
                .type(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
                .get(ClientResponse.class)
                .getEntity(EntityObjectContainigList.class);

        System.out.println("Object fetched");


        o.getList().remove(1);
        o.getList().remove(0);
        o.setName("world");


        res.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, o);
        System.out.println("Object updated");

        System.out.println("Done.");
    }

}
客户端看起来是这样的:

@Entity
public class ContainerObject {

     @Id
     @GeneratedValue(strategy=GenerationType.IDENTITY)
     @JsonIgnore
     private Key id;

    @ManyToOne(fetch = FetchType.LAZY)
    EntityObjectContainigList eocl;


    private String s;

    private int i;


    public String getS() {
            return s;
    }

    public void setS(String s) {
        this.s = s;
    }

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }


}
@Path("/db")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class MyResourcse {

    private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("transactions-optional");

    @PUT
    public Response putInDb(EntityObjectContainigList d) {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();
/*          Gson g = new Gson();
            System.out.println(g.toJson(d));*/
            em.persist(d);
            return Response.ok().build();
        } finally {
            if (em != null && em.isOpen()) em.close();
        }
    }

    @GET
    public Response getFromDb(@QueryParam("id")Long id) {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();
/*          Gson g = new Gson();*/
            EntityObjectContainigList o = em.find(EntityObjectContainigList.class, id);
/*          System.out.println(g.toJson(o));*/
            return Response.ok(o).build();
        } finally {
            if (em != null && em.isOpen()) em.close();
        }
    }

    @POST
    public Response updateDb(EntityObjectContainigList d) {
        EntityManager em = null;
        try {
            em = emf.createEntityManager();
            Gson g = new Gson();
            d =  em.merge(d);
            System.out.println(g.toJson(d));
            return Response.ok().build();
        } finally {
            if (em != null && em.isOpen()) em.close();
        }
    }
}
public class UpdateClient {

    public static void main(String[] args) {
        ClientConfig cc = new DefaultClientConfig();
        cc.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);

        Client client = Client.create(cc);

        WebResource res = client.resource("http://localhost:8888/rest/db");


        EntityObjectContainigList o = new EntityObjectContainigList();
        o.setId(12L);
        o.setName("hello");

        for (int i = 0; i < 5; i++) {
            ContainerObject c = new ContainerObject();
            c.setI(i);
            c.setS("foo" + i );
            o.getList().add(c);
        }


        res.type(MediaType.APPLICATION_JSON).put(ClientResponse.class, o);

        System.out.println("Object inserted");

        o = res.queryParam("id", "12")
                .type(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
                .get(ClientResponse.class)
                .getEntity(EntityObjectContainigList.class);

        System.out.println("Object fetched");


        o.getList().remove(1);
        o.getList().remove(0);
        o.setName("world");


        res.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, o);
        System.out.println("Object updated");

        System.out.println("Done.");
    }

}
公共类UpdateClient{
公共静态void main(字符串[]args){
ClientConfig cc=newdefaultclientconfig();
cc.getFeatures().put(JSONConfiguration.FEATURE\u POJO\u映射,Boolean.TRUE);
Client=Client.create(cc);
WebResource res=client.resource(“http://localhost:8888/rest/db");
EntityObjectContainigList o=新的EntityObjectContainigList();
o、 setId(12L);
o、 setName(“你好”);
对于(int i=0;i<5;i++){
ContainerObject c=新的ContainerObject();
c、 setI(i);
c、 集合(“foo”+i);
o、 getList().add(c);
}
res.type(MediaType.APPLICATION_JSON).put(ClientResponse.class,o);
System.out.println(“插入对象”);
o=res.queryParam(“id”,“12”)
.type(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.get(ClientResponse.class)
.getEntity(EntityObjectContainigList.class);
System.out.println(“获取的对象”);
o、 getList()。删除(1);
o、 getList()。删除(0);
o、 setName(“世界”);
res.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).post(ClientResponse.class,o);
System.out.println(“对象更新”);
System.out.println(“完成”);
}
}
我将GAE1.7.2与JPA2.0一起使用

非常感谢您的帮助。
维塔利

如何修复:

将要从
列表中删除的每个元素的
eocl
设置为
null

到底是什么问题:

双向关系的双方,

  • 拥有方(由
    mappedBy
    指向的方)和
  • 反向侧(一个带有
    mappedBy
  • 不相等,因为数据库仅根据拥有方中的值进行修改。在您的案例中,
    ContainerObject
    中的字段
    eocl
    拥有关系。因为您只修改了反面(
    列表
    ),所以并没有什么可以持久化的。要保持更改,应修改eocl
    。建议修改两侧,否则内存中的对象图不一致

    在JPA 2.0规范中,这是通过以下文字来说明的:

    关系可以是双向的,也可以是单向的。双向的 关系既有拥有方,也有反向(非拥有方)。 单向关系只有一个拥有方。拥有方 关系的更新决定了 数据库,如第3.2.4节所述。

    托管实体之间的双向关系将基于 关系的拥有方持有的引用。它是 开发人员有责任保留内存中的引用 拥有方和持有方在相反方与 当他们改变的时候,他们会互相帮助


    嗨@Mikko,再次感谢您的详细回答。由于我希望使用
    em.merge()
    updateDb(EntityObjectContainigList d)
    中接收的对象不包含我希望删除的所有元素,这意味着我无法将
    eocl
    设置为
    null
    。我应该提到我使用了谷歌数据存储。现在我改用mysql数据库,一切都正常了。