Joincolumn vs Mappedby

Source: Internet
Author: User
Tags flushes

StackOverflow has a topic Joincolumn vs mappedby very interesting:

@Entitypublic class Company {    @OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY)    @JoinColumn(name = "companyIdRef", referencedColumnName = "companyId")    private List<Branch> branches;...}
@Entitypublic class Company {    @OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY, mappedBy = "companyIdRef")    private List<Branch> branches;    ...}

What is the difference between the two types of cascading?

There are two high-score answers below the original question. Unfortunately for my this kind of slag, read or confused.

If you can't understand what people are writing, then you can tune in.

Prepare the Environment

AX, prepare the debugging environment first.

I am using Spring Boot 2.0 + Spring Data JPA 2.0, hibernate version is 5.2.14.

Start with Hibernate's debug options in spring Boot application.yml.

spring:  jpa:    properties:      hibernate:        show_sql: true  # 打印SQL语句        format_sql: true  # 格式化SQL语句        use_sql_comments: true  # 增加注释信息,就知道语句对应的Entity类型了        generate_statistics: true  # 统计信息,给出了每一步的耗时信息

Also log information at the level at which log is configured to open org.hibernate.type debug . I'm using log4j2, and I need to add it to the Log4j2.yml file:

Configuration:  Loggers    Logger:      - name: org.hibernate.type        additivity: false        level: trace  # 这个最关键        AppenderRef:          - ref: CONSOLE          - ref: ROLLING_FILE
First time Test

The original topic used is the "company-department" model, I here have a ready-made "departmental-employee" model, directly reused. The truth is the same.

 @Entity  @ Table  (Name= "Department_demo" ) public   Department { @Id   @GeneratedValue  (strategy = Generationt Ype.    identity ) private     Integer ID; private     String name;  @OneToMany  (cascade = Cascadetype.) all , orphanremoval = true , fetch = Fetchtype. eager , Mappedby =  "DepartmentID" ) private         set<employee> Employeeset = new  hashset<> (); //Setters & Getters }  
@Entity@Table(name="employee_demo")publicclass Employee {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Integer id;    private String name;    private Integer departmentId;        // setters & getters}

Here, Department uses the primary key one id -to-many properties associated with the employee departmentId .

Then just save an object to see.

@Service Public classDepartmentservice {@AutowiredDepartmentrepository departmentrepository;@PostConstruct       Public void Insertnewrecord() {Department Department =New Department(); Department.SetName("Leader"); Departmentrepository.Save(department); Employee emily =New Employee(); Emily.SetName("David"); Employee Alice =New Employee(); Alice.SetName("Wang Dali"); Department.AddEmployee(Emily); Department.AddEmployee(Alice); Departmentrepository.Save(department); }}

After startup, I found that it was printed in log.

2018-04-22 09:11:22,155:info Restartedmain (statisticalloggingsessioneventlistener.java:258)-Session Metrics {0 Nano    Seconds spent acquiring 0 JDBC connections;    0 Nanoseconds spent releasing 0 JDBC connections;    0 Nanoseconds spent preparing 0 JDBC statements;    0 nanoseconds spent executing 0 JDBC statements;    0 nanoseconds spent executing 0 JDBC batches;    0 Nanoseconds spent performing 0 L2C puts;    0 Nanoseconds spent performing 0 l2c hits;    0 Nanoseconds spent performing 0 l2c misses;    0 Nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections); 0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 Collections)}hibernate:/* Inser         T com.example.demo.model.PO.Department */INSERT INTO Department_demo (name) VALUES (?) 2018-04-22 09:11:22,314:trace Restartedmain (basicbinder.java:65)-binding parameter [1] as [VARCHAR]-[Leader]hibernat  E:   Select Currval (' department_demo_id_seq ') 2018-04-22 09:11:22,438:info restartedmain (statisticalloggingsessioneve    ntlistener.java:258)-Session Metrics {733681 nanoseconds spent acquiring 1 JDBC connections;    0 Nanoseconds spent releasing 0 JDBC connections;    6711770 Nanoseconds spent preparing 2 JDBC statements;    75097150 Nanoseconds spent executing 2 JDBC statements;    0 nanoseconds spent executing 0 JDBC batches;    0 Nanoseconds spent performing 0 L2C puts;    0 Nanoseconds spent performing 0 l2c hits;    0 Nanoseconds spent performing 0 l2c misses;    14646304 Nanoseconds spent executing 1 flushes (flushing a total of 1 entities and 1 collections); 0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 Collections)}hibernate:/* Load         Com.example.demo.model.PO.Department */Select Department0_.id as id1_1_1_, department0_.name as name2_1_1_, employeese1_.department_id as departme2_2_3_, Employeese1_.id as id1_2_3_, employeese1_.id as id1_2_0_, employeese1_.department_id as departme2_2_0_, Employe Ese1_.name as name3_2_0_ from Department_demo department0_ left outer join Employee_demo EMPLOYEESE1 _ on department0_.id=employeese1_.department_id where Department0_.id=?2018-04-22 09:11:22,460:trac E Restartedmain (basicbinder.java:65)-binding parameter [1] as [INTEGER]-[33]2018-04-22 09:11:22,499:trace RESTARTEDMA In (basicextractor.java:51)-Extracted value ([id1_2_0_]: [INTEGER])-[Null]2018-04-22 09:11:22,502:trace Restartedmai N (basicextractor.java:61)-Extracted value ([name2_1_1_]: [VARCHAR])-[leader]2018-04-22 09:11:22,503:trace restarted Main (basicextractor.java:51)-Extracted value ([departme2_2_3_]: [INTEGER])-[null]hibernate:/* Insert Com.exampl E.demo.model.po.employee */INSERT INTO Employee_demo (department_id, name) v Alues (?,?) 2018-04-22 09:11:22,516:trace Restartedmain (basicbinder.java:65)-binding parameter [1] as [INTEGER]-[33]2018-04-22 09:11        : 22,516:trace Restartedmain (basicbinder.java:65)-binding parameter [2] as [VARCHAR]-[David]hibernate:select Currval (' Employee_demo_id_seq ') Hibernate:/* Insert Com.example.demo.model.PO.Employee */Insert int o Employee_demo (department_id, name) VALUES (?,?) 2018-04-22 09:11:22,526:trace Restartedmain (basicbinder.java:65)-binding parameter [1] as [INTEGER]-[33]2018-04-22 09 : 11:22,527:trace Restartedmain (basicbinder.java:65)-binding parameter [2] as [VARCHAR]-[Wang Dali]hibernate:sele CT currval (' employee_demo_id_seq ')
Second Test

The second time the Cascade annotations of the department were modified.

@Entity@Table(name="department_demo")public class Department {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Integer id;    private String name;    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)    @JoinColumn(name="departmentId", referencedColumnName = "id")    private Set<Employee> employeeSet = new HashSet<>();

The printed log is like this.

2018-04-22 09:16:29,366:info Restartedmain (statisticalloggingsessioneventlistener.java:258)-Session Metrics {0 Nano    Seconds spent acquiring 0 JDBC connections;    0 Nanoseconds spent releasing 0 JDBC connections;    0 Nanoseconds spent preparing 0 JDBC statements;    0 nanoseconds spent executing 0 JDBC statements;    0 nanoseconds spent executing 0 JDBC batches;    0 Nanoseconds spent performing 0 L2C puts;    0 Nanoseconds spent performing 0 l2c hits;    0 Nanoseconds spent performing 0 l2c misses;    0 Nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections); 0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 Collections)}hibernate:/* Inser         T com.example.demo.model.PO.Department */INSERT INTO Department_demo (name) VALUES (?) 2018-04-22 09:16:29,478:trace Restartedmain (basicbinder.java:65)-binding parameter [1] as [VARCHAR]-[Leader]hibernat  E:   Select Currval (' department_demo_id_seq ') 2018-04-22 09:16:29,513:info restartedmain (statisticalloggingsessioneve    ntlistener.java:258)-Session Metrics {743154 nanoseconds spent acquiring 1 JDBC connections;    0 Nanoseconds spent releasing 0 JDBC connections;    4202462 Nanoseconds spent preparing 2 JDBC statements;    9628594 Nanoseconds spent executing 2 JDBC statements;    0 nanoseconds spent executing 0 JDBC batches;    0 Nanoseconds spent performing 0 L2C puts;    0 Nanoseconds spent performing 0 l2c hits;    0 Nanoseconds spent performing 0 l2c misses;    11708469 Nanoseconds spent executing 1 flushes (flushing a total of 1 entities and 1 collections); 0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 Collections)}hibernate:/* Load         Com.example.demo.model.PO.Department */Select Department0_.id as id1_1_1_, department0_.name as name2_1_1_, employeese1_.department_id as departme2_2_3_, employeese1_.id as id1_2_3_, employeese1_.id as id1_2_0_, employeese1_.department_id as departme2_2_0_, employee              Se1_.name as name3_2_0_ from Department_demo department0_ left outer join Employee_demo Employeese1_  On department0_.id=employeese1_.department_id where Department0_.id=?2018-04-22 09:16:29,529:trace Restartedmain (BASICBINDER.JAVA:65)-binding parameter [1] as [INTEGER]-[34]2018-04-22 09:16:29,538:trace Restartedmai  N (basicextractor.java:51)-Extracted value ([id1_2_0_]: [INTEGER])-[Null]2018-04-22 09:16:29,541:trace Restartedmain (basicextractor.java:61)-Extracted value ([name2_1_1_]: [VARCHAR])-[Leader]2018-04-22 09:16:29,542:trace RestartedM Ain (basicextractor.java:51)-Extracted value ([departme2_2_3_]: [INTEGER])-[null]hibernate:/* Insert Com.example . demo.model.PO.Employee */INSERT INTO Employee_demo (department_id, name) va Lues (?,?) 2018-04-22 09:16:29,552:trace Restartedmain (basicbinder.java:65)-binding parameter [1] as [INTEGER]-[34]2018-04-22 09:16:        29,552:trace Restartedmain (basicbinder.java:65)-binding parameter [2] as [VARCHAR]-[Wang dali]hibernate:select         Currval (' Employee_demo_id_seq ') Hibernate:/* Insert Com.example.demo.model.PO.Employee */insert Into Employee_demo (department_id, name) VALUES (?,?) 2018-04-22 09:16:29,555:trace Restartedmain (basicbinder.java:65)-binding parameter [1] as [INTEGER]-[34]2018-04-22 09        : 16:29,556:trace Restartedmain (basicbinder.java:65)-binding parameter [2] as [VARCHAR]-[David]hibernate:select Currval (' Employee_demo_id_seq ') Hibernate:/* Create One-to-many Row Com.example.demo.model.PO.Department.employe     ESet */update employee_demo set department_id=? where Id=?2018-04-22 09:16:29,576:trace restartedmain (basicbinder.java:65)-binding parameter [1] as [INTEGER]-[34]2018-04-22 09:16:29,577:trace Restartedmain (basicbinder.java:65)-binding parameter [2] as [INTE GER]-[30]hibernate:/* Create One-to-many Row Com.example.demo.model.PO.Department.employeeSet */Update Empl     Oyee_demo set department_id=? where Id=?2018-04-22 09:16:29,595:trace restartedmain (basicbinder.java:65)-binding parameter [1] as [INTEGER]- [34]2018-04-22 09:16:29,596:trace Restartedmain (basicbinder.java:65)-binding parameter [2] as [INTEGER]-[29]2018-04- 09:16:29,600:info Restartedmain (statisticalloggingsessioneventlistener.java:258)-Session Metrics {225339 nanosec    Onds spent acquiring 1 JDBC connections;    0 Nanoseconds spent releasing 0 JDBC connections;    731494 Nanoseconds spent preparing 7 JDBC statements;    24985288 Nanoseconds spent executing 7 JDBC statements;    0 nanoseconds spent executing 0 JDBC batches;    0 Nanoseconds spent performing 0 L2C puts; 0 Nanoseconds spent performing 0 l2c HIts    0 Nanoseconds spent performing 0 l2c misses;    35806114 Nanoseconds spent executing 1 flushes (flushing a total of 3 entities and 1 collections); 0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)}
Simple analysis

Comparing log, we can see that two times when a new employee object is persisted, it will:

    1. Executes a LEFT JOIN query statement, querying all employee objects associated with the department
    2. Each new Employee object performs an insert operation

The difference is that when you use JoinColumn annotations for the second time, log displays: each new Employee object executes an UPDATE statement and updates the foreign key .

The reason is that the mappedBy assignment operation of the foreign key is delegated to the Employee object. Instead, JoinColumn you choose to constrain the association of the foreign key by the Department object itself.

There are only a few differences between the two annotations, but the final result varies greatly. More write operations, in the production environment is easy to make a great pressure on the database. departmentIdIt is clearly a more appropriate scenario to complete the assignment of the Employee object properties in your code.

In fact, the above two scenarios are OneToMany Example 2, example 3, annotated in the JPA API documentation.

Two-way annotations of example 1 can also avoid redundant write operations.

Resources
    1. [JAVAEE-JPA] Performance optimization: How to locate performance issues
    2. The best of the @OneToMany relationship with JPA and Hibernate

Joincolumn vs Mappedby

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.