The JPA JPA lazy loading data loading LAZY lazy and real-time load EAGER (b)

JPA lazy loading LAZY data and real-time load EAGER (b)

 

   LAZY lazy loading concept and real-time load EAGER, and are widely used in a variety of development languages. The aim is to achieve selective loading of the associated data, when the attribute is lazy loading is referenced, it generates a query, extract the associated data. The real-time load is finished after the implementation of the main query, regardless of whether or not referenced, immediately perform subsequent related data query. The community was felt lazy loading this function relatively tasteless, this kind of thing eyes of the beholder, the wise see wisdom you, personally feel according to their own business on the scene.

   Btw, using lazy loading to call associated data, you must make sure the query session (database connection session) life cycle is not over, otherwise, you are unable to extract the data. In the Spring Data JPA session on how to control their life cycle, this function I have not studied as the next research topic.

   When parsing instance lazily loaded with real-time today, you need the help of entity-relational mapping function, configure-to-many (OneToMany) between entities and many to one (ManyToOne) relationship. Of course, there OneToOne, ManyToMany relationship, this study on their own if you are interested we got.

   First, add one to many relationship as an entity class ProcessBlock and Node. In this example I is ProcessBlock process definition class, corresponding to a plurality of process definition process node, i.e., Node table. The code is given below.  

   1, ProcessBlock entity definition

Copy the code
@Entity(name = "nbpm_processblock")
@NamedQuery(name = "ProcessBlock.findByName", query = "select p from nbpm_processblock p where p.name=?1")
public class ProcessBlock implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "id")
    long id;
    @Column(name = "name")
    String name;
    @Column(name = "description")
    String description;
    @OneToMany(mappedBy="processblock",cascade=CascadeType.ALL,fetch = FetchType.EAGER)
    Set<Node> nodeSet = new HashSet<Node>();
    public long getId() {
        return id;
    }
……
Copy the code

  Defined Set <Node> Properties nodeSet, to add annotations @OneToMany, means that the entity corresponding to a plurality of Node ProcessBlock nodes. Notes property mappedBy, refers to the relationship can be obtained from the Node class processblock property; cascade property to CascadeType.ALL, is that the Lord built from the table a comprehensive cascade relationship; fetch property to FetchType.EAGER, it refers to the load rules It is instantly loaded. View source code will find that by default, OneToMany annotation fetch attribute set is FetchType.LAZY.

  2, Node entity definition

Copy the code
@Entity(name = "nbpm_node")
public class Node implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "id")
    long id;
    @Column(name = "name")
    String name;
    @Column(name = "description")
    String description;
    @Column(name = "subclass")
    String subclass;
    /**
     * 关联关系必须存在
     */
    @ManyToOne(optional = true)
    @JoinColumn(name="processblock")
    ProcessBlock processblock;
    public long getId() {
        return id;
    }   
……
Copy the code

   Define ProcessBlock property processblock, to add annotations @ManyToOne, meaning that a Node entity corresponds to a ProcessBlock process definition. @JoinColumn add annotations, name attribute set to "processblock", meaning that field nbpm_node The processBlock table is a foreign key and primary key recommendations ProcessBlock relationship. Need to explain ManyToOne annotation attribute fetch default is FetchType.EAGER, will immediately extracted master table data corresponding to the query. This is still very careful consideration, generally associated data is loaded when the collection is lazy, is loaded on a single real-time data.

 Second, the preparation of sample queries and display the results. Query Using Custom JpaUtil tool defined tools to achieve refer to "Custom JpaUtil, quickly Hql execution logic (a)."

  1, the query ProcessBlock, trunk flow data because nodeSet property is set in real-time load to load, query completes, really got the break to see all the nodes corresponding to the information flow.

Copy the code
Map<String, Object> params = new HashMap<>();
        params.put("name", "主干流程");
        List<ProcessBlock> list = ApplicationContextUtil.instance.getJpaUtil().list(
                "select u from simm.spring.entity.ProcessBlock u where u.name=:name", params, ProcessBlock.class);
        
        Set<Node> nodes = list.get(0).getNodeSet();
Copy the code

 

  

Copy the code
-- Hibernate框架生成的查询语句 -----------------
Hibernate: select processblo0_.id as id1_2_, processblo0_.description as descript2_2_, processblo0_.name as name3_2_ from nbpm_processblock processblo0_ where processblo0_.name=?
Hibernate: select nodeset0_.processblock as processb5_1_0_, nodeset0_.id as id1_1_0_, nodeset0_.id as id1_1_1_, nodeset0_.description as descript2_1_1_, nodeset0_.name as name3_1_1_, 
                  nodeset0_.processblock as processb5_1_1_, nodeset0_.subclass as subclass4_1_1_ 
           from nbpm_node nodeset0_ where nodeset0_.processblock=?
Hibernate: select nodeset0_.processblock as processb5_1_0_, nodeset0_.id as id1_1_0_, nodeset0_.id as id1_1_1_, nodeset0_.description as descript2_1_1_, nodeset0_.name as name3_1_1_, 
                  nodeset0_.processblock as processb5_1_1_, nodeset0_.subclass as subclass4_1_1_ 
           from nbpm_node nodeset0_ where nodeset0_.processblock=?
Hibernate: select nodeset0_.processblock as processb5_1_0_, nodeset0_.id as id1_1_0_, nodeset0_.id as id1_1_1_, nodeset0_.description as descript2_1_1_, nodeset0_.name as name3_1_1_, 
                  nodeset0_.processblock as processb5_1_1_, nodeset0_.subclass as subclass4_1_1_ 
           from nbpm_node nodeset0_ where nodeset0_.processblock=?
Hibernate: select nodeset0_.processblock as processb5_1_0_, nodeset0_.id as id1_1_0_, nodeset0_.id as id1_1_1_, nodeset0_.description as descript2_1_1_, nodeset0_.name as name3_1_1_, 
                  nodeset0_.processblock as processb5_1_1_, nodeset0_.subclass as subclass4_1_1_ 
           from nbpm_node nodeset0_ where nodeset0_.processblock=?
Copy the code

  2, the class attribute is set to nodeSet ProcessBlock LAZY lazy loading, inquiry, the information corresponding to the discovered node lists acquired unlikely. Here lazy loading of data can not be read because the main query session has ended.

@OneToMany(mappedBy="processblock",cascade=CascadeType.ALL,fetch = FetchType.LAZY)
    //@JoinColumn(name="processblock_id")
    Set<Node> nodeSet = new HashSet<Node>();

   

- Hibernate framework to generate query ----------------- 
Hibernate: the SELECT processblo0_.id AS id1_2_, processblo0_.description AS descript2_2_, processblo0_.name AS name3_2_ from nbpm_processblock processblo0_ the WHERE processblo0_ .name =?

  3, Hql direct inquiries related properties

List<Node> nodeList = ApplicationContextUtil.instance.getJpaUtil().list(
                "select u.nodeSet from simm.spring.entity.ProcessBlock u where u.id=1", null, Node.class);
Copy the code
-- Hibernate框架生成的查询语句 -----------------
Hibernate: select nodeset1_.id as id1_1_, nodeset1_.description as descript2_1_, nodeset1_.name as name3_1_, nodeset1_.processblock as processb5_1_, nodeset1_.subclass as subclass4_1_ 
           nbpm_processblock processblo0_ inner join nbpm_node nodeset1_ on processblo0_.id=nodeset1_.processblock where processblo0_.id=1
Hibernate: select processblo0_.id as id1_2_0_, processblo0_.description as descript2_2_0_, processblo0_.name as name3_2_0_ 
           from nbpm_processblock processblo0_ where processblo0_.id=?
Copy the code

 

  So far, the main content of the test say finished, commissioning and fine details more complicated this is no longer the table. At last there is a question with you the next exchange, there is a optional attribute source in the labeling of the property defaults to true, namely the association between the primary table can be null, set to false in ManyToOne this annotation, the associated relationship Can not be empty. I guess after setting this relationship, resulting sql statements may be different, or what caused the error system is running. But tests found no influence, sql statements are left join association outer, is set to false, empty relationships will not cause an error, it seems no effect, debugging source code does not yet have found his calling logic. Friends know the proper way this feature? Can help me, thank you!

   LAZY lazy loading concept and real-time load EAGER, and are widely used in a variety of development languages. The aim is to achieve selective loading of the associated data, when the attribute is lazy loading is referenced, it generates a query, extract the associated data. The real-time load is finished after the implementation of the main query, regardless of whether or not referenced, immediately perform subsequent related data query. The community was felt lazy loading this function relatively tasteless, this kind of thing eyes of the beholder, the wise see wisdom you, personally feel according to their own business on the scene.

   Btw, using lazy loading to call associated data, you must make sure the query session (database connection session) life cycle is not over, otherwise, you are unable to extract the data. In the Spring Data JPA session on how to control their life cycle, this function I have not studied as the next research topic.

   When parsing instance lazily loaded with real-time today, you need the help of entity-relational mapping function, configure-to-many (OneToMany) between entities and many to one (ManyToOne) relationship. Of course, there OneToOne, ManyToMany relationship, this study on their own if you are interested we got.

   First, add one to many relationship as an entity class ProcessBlock and Node. In this example I is ProcessBlock process definition class, corresponding to a plurality of process definition process node, i.e., Node table. The code is given below.  

   1, ProcessBlock entity definition

Copy the code
@Entity(name = "nbpm_processblock")
@NamedQuery(name = "ProcessBlock.findByName", query = "select p from nbpm_processblock p where p.name=?1")
public class ProcessBlock implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "id")
    long id;
    @Column(name = "name")
    String name;
    @Column(name = "description")
    String description;
    @OneToMany(mappedBy="processblock",cascade=CascadeType.ALL,fetch = FetchType.EAGER)
    Set<Node> nodeSet = new HashSet<Node>();
    public long getId() {
        return id;
    }
……
Copy the code

  Defined Set <Node> Properties nodeSet, to add annotations @OneToMany, means that the entity corresponding to a plurality of Node ProcessBlock nodes. Notes property mappedBy, refers to the relationship can be obtained from the Node class processblock property; cascade property to CascadeType.ALL, is that the Lord built from the table a comprehensive cascade relationship; fetch property to FetchType.EAGER, it refers to the load rules It is instantly loaded. View source code will find that by default, OneToMany annotation fetch attribute set is FetchType.LAZY.

  2, Node entity definition

Copy the code
@Entity(name = "nbpm_node")
public class Node implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "id")
    long id;
    @Column(name = "name")
    String name;
    @Column(name = "description")
    String description;
    @Column(name = "subclass")
    String subclass;
    /**
     * 关联关系必须存在
     */
    @ManyToOne(optional = true)
    @JoinColumn(name="processblock")
    ProcessBlock processblock;
    public long getId() {
        return id;
    }   
……
Copy the code

   Define ProcessBlock property processblock, to add annotations @ManyToOne, meaning that a Node entity corresponds to a ProcessBlock process definition. @JoinColumn add annotations, name attribute set to "processblock", meaning that field nbpm_node The processBlock table is a foreign key and primary key recommendations ProcessBlock relationship. Need to explain ManyToOne annotation attribute fetch default is FetchType.EAGER, will immediately extracted master table data corresponding to the query. This is still very careful consideration, generally associated data is loaded when the collection is lazy, is loaded on a single real-time data.

 Second, the preparation of sample queries and display the results. Query Using Custom JpaUtil tool defined tools to achieve refer to "Custom JpaUtil, quickly Hql execution logic (a)."

  1, the query ProcessBlock, trunk flow data because nodeSet property is set in real-time load to load, query completes, really got the break to see all the nodes corresponding to the information flow.

Copy the code
Map<String, Object> params = new HashMap<>();
        params.put("name", "主干流程");
        List<ProcessBlock> list = ApplicationContextUtil.instance.getJpaUtil().list(
                "select u from simm.spring.entity.ProcessBlock u where u.name=:name", params, ProcessBlock.class);
        
        Set<Node> nodes = list.get(0).getNodeSet();
Copy the code

 

  

Copy the code
-- Hibernate框架生成的查询语句 -----------------
Hibernate: select processblo0_.id as id1_2_, processblo0_.description as descript2_2_, processblo0_.name as name3_2_ from nbpm_processblock processblo0_ where processblo0_.name=?
Hibernate: select nodeset0_.processblock as processb5_1_0_, nodeset0_.id as id1_1_0_, nodeset0_.id as id1_1_1_, nodeset0_.description as descript2_1_1_, nodeset0_.name as name3_1_1_, 
                  nodeset0_.processblock as processb5_1_1_, nodeset0_.subclass as subclass4_1_1_ 
           from nbpm_node nodeset0_ where nodeset0_.processblock=?
Hibernate: select nodeset0_.processblock as processb5_1_0_, nodeset0_.id as id1_1_0_, nodeset0_.id as id1_1_1_, nodeset0_.description as descript2_1_1_, nodeset0_.name as name3_1_1_, 
                  nodeset0_.processblock as processb5_1_1_, nodeset0_.subclass as subclass4_1_1_ 
           from nbpm_node nodeset0_ where nodeset0_.processblock=?
Hibernate: select nodeset0_.processblock as processb5_1_0_, nodeset0_.id as id1_1_0_, nodeset0_.id as id1_1_1_, nodeset0_.description as descript2_1_1_, nodeset0_.name as name3_1_1_, 
                  nodeset0_.processblock as processb5_1_1_, nodeset0_.subclass as subclass4_1_1_ 
           from nbpm_node nodeset0_ where nodeset0_.processblock=?
Hibernate: select nodeset0_.processblock as processb5_1_0_, nodeset0_.id as id1_1_0_, nodeset0_.id as id1_1_1_, nodeset0_.description as descript2_1_1_, nodeset0_.name as name3_1_1_, 
                  nodeset0_.processblock as processb5_1_1_, nodeset0_.subclass as subclass4_1_1_ 
           from nbpm_node nodeset0_ where nodeset0_.processblock=?
Copy the code

  2、将ProcessBlock类的属性nodeSet设置成懒加载LAZY,查询后,发现对应的节点列表信息获取不到了。这里懒加载的数据读取不到是因为主查询的session已经结束。

@OneToMany(mappedBy="processblock",cascade=CascadeType.ALL,fetch = FetchType.LAZY)
    //@JoinColumn(name="processblock_id")
    Set<Node> nodeSet = new HashSet<Node>();

   

-- Hibernate框架生成的查询语句 -----------------
Hibernate: select processblo0_.id as id1_2_, processblo0_.description as descript2_2_, processblo0_.name as name3_2_ from nbpm_processblock processblo0_ where processblo0_.name=?

  3、Hql直接查询关联属性

List<Node> nodeList = ApplicationContextUtil.instance.getJpaUtil().list(
                "select u.nodeSet from simm.spring.entity.ProcessBlock u where u.id=1", null, Node.class);
Copy the code
-- Hibernate框架生成的查询语句 -----------------
Hibernate: select nodeset1_.id as id1_1_, nodeset1_.description as descript2_1_, nodeset1_.name as name3_1_, nodeset1_.processblock as processb5_1_, nodeset1_.subclass as subclass4_1_ 
           nbpm_processblock processblo0_ inner join nbpm_node nodeset1_ on processblo0_.id=nodeset1_.processblock where processblo0_.id=1
Hibernate: select processblo0_.id as id1_2_0_, processblo0_.description as descript2_2_0_, processblo0_.name as name3_2_0_ 
           from nbpm_processblock processblo0_ where processblo0_.id=?
Copy the code

 

  So far, the main content of the test say finished, commissioning and fine details more complicated this is no longer the table. At last there is a question with you the next exchange, there is a optional attribute source in the labeling of the property defaults to true, namely the association between the primary table can be null, set to false in ManyToOne this annotation, the associated relationship Can not be empty. I guess after setting this relationship, resulting sql statements may be different, or what caused the error system is running. But tests found no influence, sql statements are left join association outer, is set to false, empty relationships will not cause an error, it seems no effect, debugging source code does not yet have found his calling logic. Friends know the proper way this feature? Can help me, thank you!

Guess you like

Origin www.cnblogs.com/fengli9998/p/12023527.html