在近期的我的项目中我尝试着把本利用@ManyToOne注解的中央应用@OneToOne注解,本认为进行存储或者查问等操作时会产生谬误然而并没有产生任何谬误,所有操作都能够失常执行。
所以首先我想看一下在数据库中生成的外键是否雷同。
@ApiModelProperty("车辆品牌") @ManyToOne private VehicleBrand brand; @ApiModelProperty("车辆类型") @OneToOne private VehicleType type;
咱们会发现目前在数据库中没有任何差异,那么这时我就想通过查看他们的源代码来比拟一下。
@Target({ElementType.METHOD, ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)public @interface ManyToOne { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fetch() default FetchType.EAGER; boolean optional() default true;}
@Target({ElementType.METHOD, ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)public @interface OneToOne { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fetch() default FetchType.EAGER; boolean optional() default true; String mappedBy() default ""; boolean orphanRemoval() default false;}
通过比照咱们能够发现@OneToOne只比@ManyToOne多了两项内容,mappedBy和orphanRemoval。其余部分完全一致。
MappedBy
只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性;
mappedBy标签肯定是定义在被领有方的,他指向领有方;
mappedBy示意申明本人不是一对多的关系保护端,由对方来保护,是在一的一方进行申明的。mappedBy的值应该为一的一方的表名。
mappedBy在Stack Overflow上有着更具体的解释
询问者问题:mappedBy作用
Foo实体:@ManyToMany(mappedBy = "foos")private Set<Bar> bars
Bar实体:@ManyToManyprivate Set<Foo> foos
将其中的一个答复翻译过去就是:
如果关联是双向的,则一方必须是所有者,另一方必须是反向端(即在更新关联表中的关系值时将疏忽它):所以,具备mappedby属性的边是相同的边。没有mappedby属性的一方是所有者。(mappedy在Foo中)所有者侧是Hibernate所查看的哪一个关联存在的方。因而,例如,如果在Bar的foo汇合中增加foo,hibernate将在表中插入一个新行。相同,如果在Foo的bar汇合中增加一个bar,则数据库中不会批改任何内容。
尝试着对以上内容进行论证
假如Klass和Teacher两个实体,他们的关系为多对多;
@Entitypublic class Teacher { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToMany(mappedBy = "teacherList") private List<Klass> klassList = new ArrayList<>(); }
@Entitypublic class Teacher { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; //teacher领有mappedBy属性的Klass @ManyToMany(mappedBy = "teacherList") private List<Klass> klassList = new ArrayList<>(); }
这时从klas插入teacher是能够胜利的,而从teacher插入klass是没法胜利的。
所以我尝试着在VehicleType实体中申明vehicle。
@OneToOne(mappedBy = "type") private Vehicle vehicle;
之后我再关上我的项目中相应页面时就会产生报错:
其中的 More than one row with the given identifier was found:
翻译过去就是:找到了多个具备给定标识符的行。也就合乎咱们的预期。因为之前对mappedBy的认知不清晰,也就没有要给相关联实体削减mappedBy
的习惯。
由此能够得悉mappedBy不仅仅能够做到下面那样的规定保护方的性能,还能够做到检测存储谬误的性能,所以在理论的编写中增加对应的mappedBy还是很有必要的。
至于注解中的其余属性则是对应着jpa级联(Cascade)操作
因为 重复性的操作非常繁缛,尤其是在解决多个彼此关联对象状况下,此时咱们能够应用级联(Cascade)操作。级联 在关联映射中是个重要的概念,指当被动方对象执行操作时,被关联对象(被动方)是否同步执行同一操作。
因为临时并未遇到相应的问题也就没有深刻理解,能够先对此有个概念,之后遇到相应问题时再来认真理解。
参考文章:jpa级联(Cascade)操作