Java 仅当@manytone引用的对象不存在时才持久化该对象
我对Spring/JPA相当陌生,所以这是一个有点琐碎的问题 我有两个具有多对一关系的实体:Item和ItemType。基本上,ItemType只是表示一组项的唯一名称。我用积垢储存库来储存它们。相关代码如下:getter/setters/equals/hashCode省略:Java 仅当@manytone引用的对象不存在时才持久化该对象,java,spring,jpa,Java,Spring,Jpa,我对Spring/JPA相当陌生,所以这是一个有点琐碎的问题 我有两个具有多对一关系的实体:Item和ItemType。基本上,ItemType只是表示一组项的唯一名称。我用积垢储存库来储存它们。相关代码如下:getter/setters/equals/hashCode省略: @Entity public class Item { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id;
@Entity
public class Item {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "type_id")
private ItemType itemType;
public Item() {}
public Item(ItemType itemType) {
this.itemType = itemType;
}
}
@Entity
public class ItemType {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(unique = true, nullable = false)
private String name;
public ItemType() {}
public ItemType(String name) {
this.name = name;
}
}
@Controller
public class ItemsController {
@Autowired private ItemsRepo itemsRepo;
@RequestMapping(value = "/item", method = RequestMethod.POST)
@ResponseBody
public Item addQuestionSet(@RequestBody Item item) {
return itemsRepo.save(item);
}
}
当我向数据库中插入一个新项时,我希望它从一个具有给定名称的ItemType(如果它已经存在)或者从一个新持久化的ItemType(否则)中获取一个type_id
到目前为止,我在尝试插入具有相同类型的第二项时自然会遇到一个异常:
org.hsqldb.HsqlException: integrity constraint violation: unique constraint or index violation
在将新项目保存到存储库之前,我可能会在控制器中进行样板检查。但是这个任务相当通用,我很确定JPA中一定有一个方便的解决方案
谢谢。似乎您是项对象上的持久化方法,而不是合并方法。我希望它能解决您的问题。我可以看出问题在于,当您坚持使用时,请尝试使用lazy类型。只有当你需要数据时,你才能得到它,而且总是渴望得到。 我可以给你举一个我是如何做到这一点的例子 这是我的教室
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "idCentroEstudio",nullable=false)
private Long idCentroEstudio;
@ManyToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name = "idTipoCentroEstudio", nullable = false)
private TipoCentroEstudio tipoCentroEstudio;
@Column(name="nombre",nullable=false)
private String nombre;
@Column(name="activo",nullable=false)
private boolean activo;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="idTipoCentroEstudio",nullable=false)
private Long idTipoCentroEstudio;
@Column(name="descripcion",nullable=false)
private String descripcion;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "tipoCentroEstudio")
private Set<CentroEstudio> centroEstudio = new HashSet<CentroEstudio>(0);
这是我的课,提波森特罗工作室
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "idCentroEstudio",nullable=false)
private Long idCentroEstudio;
@ManyToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name = "idTipoCentroEstudio", nullable = false)
private TipoCentroEstudio tipoCentroEstudio;
@Column(name="nombre",nullable=false)
private String nombre;
@Column(name="activo",nullable=false)
private boolean activo;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="idTipoCentroEstudio",nullable=false)
private Long idTipoCentroEstudio;
@Column(name="descripcion",nullable=false)
private String descripcion;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "tipoCentroEstudio")
private Set<CentroEstudio> centroEstudio = new HashSet<CentroEstudio>(0);
我为例子中的西班牙语感到抱歉,但我是秘鲁人,我会说西班牙语。
我希望这能帮助你 谢谢你的回复。我从不显式调用这些函数,而是使用crudepository的save方法保存对象。save方法不应该以某种方式从模式派生吗?如果我删除CascadeType.PERSIST,我会得到org.hibernate.TransientPropertyValueException:对象引用了一个未保存的临时实例-在Flushing之前保存该临时实例。但我没有,我的理解是Spring是根据模式在引擎盖下完成的。