3

In a recent project, I tried to use the @OneToOne annotation in the place annotated with @ManyToOne in this application. I thought that an error would occur during storage or query operations, but no error occurred, and all operations can be performed normally.
So first I want to see if the foreign keys generated in the database are the same.
图片.png

  @ApiModelProperty("车辆品牌")
  @ManyToOne
  private VehicleBrand brand;

  @ApiModelProperty("车辆类型")
  @OneToOne
  private VehicleType type;

We'll see that there are currently no differences in the database, so at this point I'd like to compare by looking at their source code.

@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;
}

By comparison, we can find that @OneToOne only has two more contents than @ManyToOne, mappedBy and orphanRemoval. The rest is exactly the same.

MappedBy

Only OneToOne, OneToMany, ManyToMany have the mappedBy attribute, and ManyToOne does not have this attribute;
The mappedBy tag must be defined on the owned side, and it points to the owning side;

mappedBy means to declare that it is not a one-to-many relationship maintenance end, it is maintained by the other party, and it is declared on one side. The value of mappedBy should be the table name of the one side.

mappedBy has a more detailed explanation on Stack Overflow
Asker question: mappedBy role

Foo实体:

@ManyToMany(mappedBy = "foos")
private Set<Bar> bars
Bar实体:

@ManyToMany
private Set<Foo> foos

A translation of one of the answers is:

如果关联是双向的,则一方必须是所有者,另一方必须是反向端(即在更新关联表中的关系值时将忽略它):
所以,具有mappedby属性的边是相反的边。没有mappedby属性的一方是所有者。(mappedy在Foo中)
所有者侧是Hibernate所查看的哪一个关联存在的方。因此,例如,如果在Bar的foo集合中添加foo,
hibernate将在表中插入一个新行。相反,如果在Foo的bar集合中添加一个bar,则数据库中不会修改任何内容。

try to argue for the above
Suppose Klass and Teacher are two entities, and their relationship is many-to-many;

@Entity
public class Teacher  {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    
    @ManyToMany(mappedBy = "teacherList")
    private List<Klass> klassList = new ArrayList<>();
    
}
@Entity
public class Teacher  {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    //teacher拥有mappedBy属性的Klass
    @ManyToMany(mappedBy = "teacherList")
    private List<Klass> klassList = new ArrayList<>();
    
}

At this time, inserting teacher from klas can be successful, but inserting klass from teacher cannot be successful.

So I tried declaring the vehicle in the VehicleType entity.

  @OneToOne(mappedBy = "type")
  private Vehicle vehicle;

After that, when I open the corresponding page in the project, an error occurs:
图片.png
The translation of More than one row with the given identifier was found: is: More than one row with the given identifier was found. Also in line with our expectations. Due to the unclear understanding of mappedBy before, there is no habit of adding mappedBy to the associated entity.

From this, it can be known that mappedBy can not only achieve the function of specifying the maintainer as above, but also can detect storage errors, so it is necessary to add the corresponding mappedBy in the actual writing.

As for other attributes in the annotation, it corresponds to jpa cascade (Cascade) operation

Since repetitive operations are very cumbersome, especially when dealing with multiple objects that are related to each other, we can use cascade operations at this time. Cascading is an important concept in association mapping, which refers to whether the associated object (passive) performs the same operation synchronously when the active object performs an operation.
Since I haven't encountered the corresponding problem for the time being, I have no in-depth understanding. You can have a concept of this first, and then come to know it carefully when you encounter the corresponding problem.
Reference article:
jpa cascade (Cascade) operation

Small problem: When creating a new background entity, make sure that the field names of the foreground entity are consistent, otherwise, the returned information will not match the foreground entity.
For example, if the color field set in the foreground is color and the background is colour, then the foreground cannot receive the color field returned by the background.


李明
441 声望18 粉丝