【问题标题】:JPA persit creates new existing entity in many to one relationJPA 坚持在多对一关系中创建新的现有实体
【发布时间】:2015-06-20 21:32:35
【问题描述】:

我是 JPA 的新手,我的项目中有以下实体:

动物实体:

package com.shop.model;

import java.io.Serializable;

import javax.persistence.*;

@Entity
@NamedQueries({
    @NamedQuery(name="Animal.findAll", query="SELECT a FROM Animal a"),
    @NamedQuery(name="Animal.findAllByTypeId", query="SELECT a FROM Animal a WHERE a.type.id = :id"),
})
public class Animal implements Serializable {
    private static final long serialVersionUID = 1L;
    public static String SMALL = "small";
    public static String MEDIUM = "medium";
    public static String LARGE = "large";

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

    @Lob
    private String description;

    private String name;

    private String size;

    @ManyToOne(cascade=CascadeType.PERSIST)
    private Type type;

    public Animal() {
    }

    public int getId() {
        return this.id;
    }

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

    public String getDescription() {
        return this.description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getName() {
        return this.name;
    }

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

    public String getSize() {
        return this.size;
    }

    public void setSize(String size) {
        this.size = size;
    }

    public Type getType() {
        return this.type;
    }

    public void setType(Type type) {
        this.type = type;
    }

}

类型实体:

package com.shop.model;

import java.io.Serializable;
import javax.persistence.*;
import java.sql.Timestamp;
import java.util.List;

@Entity
@NamedQueries({
    @NamedQuery(name="Type.findAll", query="SELECT t FROM Type t"),
})
public class Type implements Serializable {
    private static final long serialVersionUID = 1L;

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

    private Timestamp created;

    private String name;

    @OneToMany(mappedBy="type", cascade=CascadeType.PERSIST)
    private List<Animal> animals;

    public Type() {
    }

    public int getId() {
        return this.id;
    }

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

    public Timestamp getCreated() {
        return this.created;
    }

    public void setCreated(Timestamp created) {
        this.created = created;
    }

    public String getName() {
        return this.name;
    }

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

    public List<Animal> getAnimals() {
        return this.animals;
    }

    public void setAnimals(List<Animal> animals) {
        this.animals = animals;
    }

    public Animal addAnimal(Animal animal) {
        getAnimals().add(animal);
        animal.setType(this);

        return animal;
    }

    public Animal removeAnimal(Animal animal) {
        getAnimals().remove(animal);
        animal.setType(null);

        return animal;
    }
}

我正在创建新类型:

Type type = new Type();
type.setName("Some new animal type");
this.entityManager.getTransaction().begin();
this.entityManager.persit(type);
this.entityManager.getTransaction().commit();
int lastInsertId = type.getId(); // wotks great!

但是,当我尝试使用现有类型保留新动物时,JPA 会创建 一种新的类型。这是一个例子

Animal animal = new Animal();
Type type = this.entityManager.getReference(Type.class, 9);

animal.setName(name);
animal.setDescription(description);
animal.setSize(size);
animal.setType(type);

this.entityManager.getTransaction().begin();
this.entityManager.persit(animal);
this.entityManager.getTransaction().commit();
int lastId = animal.getId(); // works great !

它工作正常(创建了一个新动物),但它也创建了一个新类型,这就是问题所在。我也尝试了 find(Object object, int id) 方法,但它仍然创建了一个新类型。

我尝试使用 merge 方法而不是 persit,它工作正常!!!但是 getId 正在返回 0 值。

我需要使用现有类型创建一个新动物,并获取最后一个 id。这可能吗?

【问题讨论】:

    标签: java hibernate jpa insert


    【解决方案1】:

    你应该使用合并:

        Entity entity=entityManager.merge(newEntity);
        int lastId=entity.getId();
    

    获取对对象的引用并在持久化后获取其 id 不需要,因为实体在持久化之后已经被管理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-17
      • 1970-01-01
      • 2014-10-26
      • 2013-01-30
      • 1970-01-01
      • 2016-05-13
      • 2016-10-28
      • 1970-01-01
      相关资源
      最近更新 更多