EclipseLink的延迟加载挂在引用类(EclipseLink lazy loading han

2019-10-16 21:55发布

我试图查询a person by id ,在我的模式下面,我有一个@OneToMany之间的参考AddressPersonManyToOne人与学校之间的参考。 我使用了一个命名查询和查询提示,以获得(有关部分发布)这个简单的任务,但看着堆栈跟踪性能最佳的查询,生成的EclipseLink三个select语句时,我要的是ID人物对象? 用渴望获取被查杀性能,因此我的问题是如何能够简单地创建使用JPQL,通过ID让我一个人对象的查询,而不引用其他类?

@NamedQuery(
        name="findPersonById",
        query="SELECT p FROM Person as p  WHERE p.id = :id",
                hints={@QueryHint(name="eclipselink.batch.type", value="JOIN"),
                @QueryHint(name="eclipselink.batch", value="p.address")
                }
)
public class Person {

    @Id
    @TableGenerator(name = "TABLE_GEN", table = "PERSON_SEQUENCE_TABLE", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "PER_SEQ", allocationSize = 1, initialValue = 10000)
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN")
    @Column(name = "personID")
    private Long id;

    @ManyToOne(cascade = CascadeType.PERSIST,fetch = FetchType.LAZY)
    @JoinColumn(name = "addressID")
    private Address address;

    @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinColumn(name = "schoolID")
    private School school;

}

地址实体

public class Address {


    @Id
    @TableGenerator(name = "ADDRESS_TABLE_GEN", table = "ADDRESS_SEQUENCE_TABLE", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "ADDR_SEQ", allocationSize = 1, initialValue = 1)
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "ADDRESS_TABLE_GEN")
    @Column(name = "addressID")
    private Long id;


    @OneToMany(cascade = CascadeType.ALL, mappedBy = "address")
    private Set<Person> persons = new HashSet<Person>();

命名查询执行

public Person getPersonQueryBatch(Long id){

    EntityManager entityManager = factory.createEntityManager();
    Person person = null;

    try {

         List<Person> results = entityManager.createNamedQuery("findPersonById")
        .setParameter("id", id)
        .getResultList();
        if(!results.isEmpty()){
            // ignores multiple results
            person = results.get(0);
        }
    } catch (NoResultException e) {
        e.printStackTrace();
    }

    entityManager.close();
    return person;

}

堆栈跟踪:它搜索的最后一位addressID ,等于1是挂

[EL Finest]: jpa: 2012-06-26 20:47:29.78--ServerSession(1259621282)--Thread(Thread[main,5,main])--Begin deploying Persistence Unit persistenceUnit; session file:/Users/warz07/Documents/workspace-sts-2.8.0.RELEASE/dugsimanager/target/classes/_persistenceUnit; state Deployed; factoryCount 2
[EL Finest]: jpa: 2012-06-26 20:47:29.781--ServerSession(1259621282)--Thread(Thread[main,5,main])--End deploying Persistence Unit persistenceUnit; session file:/Users/warz07/Documents/workspace-sts-2.8.0.RELEASE/dugsimanager/target/classes/_persistenceUnit; state Deployed; factoryCount 2
[EL Finer]: connection: 2012-06-26 20:47:29.787--ServerSession(1259621282)--Thread(Thread[main,5,main])--client acquired: 67158058
[EL Finer]: transaction: 2012-06-26 20:47:29.788--ClientSession(67158058)--Thread(Thread[main,5,main])--acquire unit of work: 1296566131
[EL Finest]: query: 2012-06-26 20:47:29.788--UnitOfWork(1296566131)--Thread(Thread[main,5,main])--Execute query ReadObjectQuery(name="findPersonById" referenceClass=Person sql="SELECT personID, TYPE, DATEADDED, FIRSTNAME, LASTNAME, MIDDLENAME, ACTIVE, BIRTHDAY, EMAILADDRESS, GENDER, IMAGEPATH, MARITAL, PRIMARYTELEPHONE, SECONDARYTELEPHONE, version, addressID, schoolID, ETHNICITY, HISPANIC, MAJOR, NATIVELANGUAGE, RELIGIOUSAFFILIATION, studentId FROM PERSON WHERE (personID = ?)")
[EL Finest]: connection: 2012-06-26 20:47:29.789--ServerSession(1259621282)--Connection(65769329)--Thread(Thread[main,5,main])--Connection acquired from connection pool [read].
[EL Finest]: connection: 2012-06-26 20:47:29.789--ServerSession(1259621282)--Thread(Thread[main,5,main])--reconnecting to external connection pool
[EL Fine]: sql: 2012-06-26 20:47:29.79--ServerSession(1259621282)--Connection(1578517945)--Thread(Thread[main,5,main])--SELECT personID, TYPE, DATEADDED, FIRSTNAME, LASTNAME, MIDDLENAME, ACTIVE, BIRTHDAY, EMAILADDRESS, GENDER, IMAGEPATH, MARITAL, PRIMARYTELEPHONE, SECONDARYTELEPHONE, version, addressID, schoolID, ETHNICITY, HISPANIC, MAJOR, NATIVELANGUAGE, RELIGIOUSAFFILIATION, studentId FROM PERSON WHERE (personID = ?)
    bind => [10000]
[EL Finest]: connection: 2012-06-26 20:47:29.798--ServerSession(1259621282)--Connection(65769329)--Thread(Thread[main,5,main])--Connection released to connection pool [read].
2012-06-26 20:47:29,802 [main] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected method of bean 'org.bixin.dugsi.domain.Student': PersistenceElement for transient javax.persistence.EntityManager org.bixin.dugsi.domain.Person.entityManager
2012-06-26 20:47:29,803 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'entityManagerFactory'
[EL Finest]: query: 2012-06-26 20:47:29.821--ServerSession(1259621282)--Thread(Thread[main,5,main])--Execute query ReadAllQuery(name="address" referenceClass=Address sql="SELECT DISTINCT t0.addressID, t0.CITY, t0.COUNTRY, t0.STATE_US, t0.STREETADDRESS, t0.STREETADDRESS2, t0.version, t0.ZIPCODE FROM ADDRESS t0, PERSON t1 WHERE ((t0.addressID = t1.addressID) AND (t1.personID = ?))")
[EL Finest]: connection: 2012-06-26 20:47:29.821--ServerSession(1259621282)--Connection(420965983)--Thread(Thread[main,5,main])--Connection acquired from connection pool [read].
[EL Finest]: connection: 2012-06-26 20:47:29.821--ServerSession(1259621282)--Thread(Thread[main,5,main])--reconnecting to external connection pool
[EL Fine]: sql: 2012-06-26 20:47:29.822--ServerSession(1259621282)--Connection(1364143063)--Thread(Thread[main,5,main])--SELECT DISTINCT t0.addressID, t0.CITY, t0.COUNTRY, t0.STATE_US, t0.STREETADDRESS, t0.STREETADDRESS2, t0.version, t0.ZIPCODE FROM ADDRESS t0, PERSON t1 WHERE ((t0.addressID = t1.addressID) AND (t1.personID = ?))
    bind => [10000]
[EL Finest]: connection: 2012-06-26 20:47:29.825--ServerSession(1259621282)--Connection(420965983)--Thread(Thread[main,5,main])--Connection released to connection pool [read].
2012-06-26 20:47:29,826 [main] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected method of bean 'org.bixin.dugsi.domain.Address': PersistenceElement for transient javax.persistence.EntityManager org.bixin.dugsi.domain.Address.entityManager
2012-06-26 20:47:29,827 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'entityManagerFactory'
2012-06-26 20:47:29,830 [main] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected method of bean 'org.bixin.dugsi.domain.Student': PersistenceElement for transient javax.persistence.EntityManager org.bixin.dugsi.domain.Person.entityManager
2012-06-26 20:47:29,831 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'entityManagerFactory'
[EL Finest]: transaction: 2012-06-26 20:47:29.832--UnitOfWork(1296566131)--Thread(Thread[main,5,main])--[EL Finest]: query: 2012-06-26 20:47:29.844--ServerSession(1259621282)--Thread(Thread[main,5,main])--Execute query ReadAllQuery(name="persons" referenceClass=Person )
[EL Finest]: connection: 2012-06-26 20:47:29.845--ServerSession(1259621282)--Connection(36219749)--Thread(Thread[main,5,main])--Connection acquired from connection pool [read].
[EL Finest]: connection: 2012-06-26 20:47:29.845--ServerSession(1259621282)--Thread(Thread[main,5,main])--reconnecting to external connection pool
[EL Fine]: sql: 2012-06-26 20:47:29.845--ServerSession(1259621282)--Connection(1007449342)--Thread(Thread[main,5,main])--SELECT personID, TYPE, DATEADDED, FIRSTNAME, LASTNAME, MIDDLENAME, ACTIVE, BIRTHDAY, EMAILADDRESS, GENDER, IMAGEPATH, MARITAL, PRIMARYTELEPHONE, SECONDARYTELEPHONE, version, addressID, schoolID, ETHNICITY, HISPANIC, MAJOR, NATIVELANGUAGE, RELIGIOUSAFFILIATION, studentId FROM PERSON WHERE (addressID = ?)
    bind => [1] 

在运行查询测试用例

public void testSavingPersonSchool(){

        PersonService personService = new PersonService();
        System.out.println("here\n");
        Person cPerson = personService.getPersonQueryBatch(Long.valueOf("10000"));
        System.out.println("not here\n");
        School school = new School();
        Address address = new Address();
        address.setStreetAddress("eer street");
        address.setCity("hiokins");
        address.setZipCode("34343");
        address.setState_us("MN");
        address.setCountry("usa");

        school.setName("Maui");
        school.setDescription("Thinking of dropping a summer class?");
        school.setAddress(address);
        school.setPrimaryPhone("3242342342");
        school.setAdmissionsPhone("3242342342");
        school.setAdmissionsEmailAddress("ads@d.com");
        school.setActive(true);
        cPerson.setSchool(school);
        school.persist();

Student.java

package org.bixin.dugsi.domain;

import java.util.HashSet;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.OneToMany;
import javax.persistence.PostPersist;
import javax.validation.constraints.NotNull;
import org.eclipse.persistence.annotations.BatchFetch;
import org.eclipse.persistence.annotations.BatchFetchType;
import org.eclipse.persistence.annotations.JoinFetch;
import org.eclipse.persistence.annotations.JoinFetchType;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.jpa.activerecord.RooJpaActiveRecord;
import org.springframework.roo.addon.tostring.RooToString;

@RooJavaBean
@RooToString
@RooJpaActiveRecord
@DiscriminatorValue("S")
public class Student extends Person {

    @Basic
    @Column(name = "studentId")
    private String studentIdentifier;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "student", fetch = FetchType.LAZY)
    private Set<Registration> registrations = new HashSet<Registration>();

    @PostPersist
    public void generateCode() {
        studentIdentifier = ("S-000-");
    }
}

Answer 1:

从这些线路:

2012-06-26 20:47:29802 [主要] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - 处理注入豆的方法 'org.bixin.dugsi.domain.Student':PersistenceElement瞬态javax.persistence。 EntityManager的org.bixin.dugsi.domain.Person.entityManager

看来,你正在做的实体类的一些注入。 需要看到完整的源代码的实体,以确保虽然。 不过,如果你这样做..好..不:)创建春天代理或每个实体做DI是一种矫枉过正,也几乎肯定会毁掉整个延迟初始化,因为同时做DI春天将访问多对一集合,触发分贝负载为那些实体。

作为一个旁注:你的实体不应该包含业务逻辑,所以我们没有理由做任何的依赖注入给他们。



Answer 2:

随着抓取设置为LAZY访问的人不应触发查询到的地址或学校。 你已经启用编织(使用代理或Java EE /春织)? 您可能需要启用动态编织或使用静态编织。

这可能是别的东西被触发的关系,你可以把一个断点,或倾倒在EclipseLink的会话查询执行堆栈跟踪(使用SessionEvent)。

你批上获取的地址是没有意义的,批量抓取是当查询返回结果很多,但你被发现的ID。 你可以使用一个连接抓取(在JPQL或者通过连接抓取提示)。

我不知道这是怎么挂,打破过程中得到堆栈跟踪,看看它正在等待。



文章来源: EclipseLink lazy loading hangs on reference class