触发器@onetomany lazy fetch

kqhtkvqz  于 2021-06-30  发布在  Java
关注(0)|答案(0)|浏览(190)

我有一个 ExampleRequest 可以选择具有一个或多个 ExampleRequestYear . 它目前是这样配置的(为了简洁起见,省略了不相关的字段和getter/setter,如果您还需要什么,请告诉我):

@Entity
@Table(name = "EXAMPLE_REQUEST")
@SequenceGenerator(name = "EXAMPLE_REQUEST_ID_SEQ", sequenceName = "EXAMPLE_REQUEST_ID_SEQ", allocationSize = 1)
@Cacheable(false)
public class ExampleRequest implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "EXAMPLE_REQUEST_ID_SEQ")
    @Column(name="EXAMPLE_REQUEST_ID", nullable = false)
    private Long exampleRequestId;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "exampleRequest")
    private List<ExampleRequestYear> exampleRequestYearList;

    public ExampleRequest() {
    }

    public List<ExampleRequestYear> getExampleRequestYearList() {
        if(this.exampleRequestYearList == null){
            this.exampleRequestYearList = new ArrayList<ExampleRequestYear>();
        }
        return this.exampleRequestYearList;
    }

    public void setExampleRequestYearList(List<ExampleRequestYear> exampleRequestYearList) {
        this.exampleRequestYearList = exampleRequestYearList;
    }

    public ExampleRequestYear addExampleRequestYear(ExampleRequestYear exampleRequestYear) {
        getExampleRequestYearList().add(exampleRequestYear);
        exampleRequestYear.setExampleRequest(this);
        return exampleRequestYear;
    }

    public ExampleRequestYear removeExampleRequestYear(ExampleRequestYear exampleRequestYear) {
        getExampleRequestYearList().remove(exampleRequestYear);
        exampleRequestYear.setExampleRequest(null);
        return exampleRequestYear;
    }
}

@Entity
@Table(name = "EXAMPLE_REQUEST_YEAR")
@IdClass(ExampleRequestYearPK.class)
public class ExampleRequestYear implements Serializable {
    @Id
    @Column(nullable = false)
    private Integer year;

    @Id
    @ManyToOne
    @JoinColumn(name = "EXAMPLE_REQUEST_ID", referencedColumnName = "EXAMPLE_REQUEST_ID")
    private ExampleRequest exampleRequest;

    public ExampleRequestYear() {
    }

    public void setExampleRequest(ExampleRequest exampleRequest) {
        this.exampleRequest = exampleRequest;
    }

    public ExampleRequest getExampleRequest() {
        return exampleRequest;
    }
}

部分代码是由ide自动生成的,我现在还在考虑jpa,所以可能有很多设计错误。
当我创建一个新的 ExampleRequest :

ExampleRequest exampleRequest = new ExampleRequest();
ExampleRequestYear exampleRequestYear = new ExampleRequestYear(2020);
request.addExampleRequestYear(exampleRequestYear);

但是,我不知道如何编辑现有的 ExampleRequest 因为我不确定该如何检索链接的实体。根据我读过的文章,延迟抓取应该是自动的,但是当我尝试这样做时:

ExampleRequest exampleRequest = employeeRequestsController.getExampleRequestById(123);
System.out.println(exampleRequest.getExampleRequestYearList().size());

... 我得到一个空指针异常 .size() 因为getter会运行,但既不会初始化空列表,也不会从db中检索项:

public List<ExampleRequestYear> getExampleRequestYearList() {
    if(this.exampleRequestYearList == null){
        // Field is null and conditional is entered
        this.exampleRequestYearList = new ArrayList<ExampleRequestYear>();
        // After initialisation, field is still null!
    }
    return this.exampleRequestYearList;
}

另外,切换到 FetchType.EAGER 完全解决了这个问题。我错过了什么?
有关应用程序设计的更多详细信息。这个 Resource 处理http请求的类与一组 Controller 像这样的课程:

@Stateless(name = "ISomeActionController", mappedName = "ISomeActionController")
public class SomeActionController implements ISomeActionController {
    @EJB
    private IFooDAO fooDao;

    @EJB
    private IBarDAO barDao;

    @Override
    public ExampleRequest getExampleRequestById(Long exampleRequestId) {
        return fooDao.getEntityById(exampleRequestId);
    }
}

在道的课堂上 EntityManager 注入的是使用过的:

@Local
public interface IGenericDAO<T> {
    public T persistEntity(T o);
    public T persistEntityCommit(T o);
    public void removeEntity(T o);
    public void removeEntity(long id);
    public T mergeEntity(T o);
    public List<T> getEntitiesFindAll();
    public List<T> getEntitiesFindAllActive();
    public T getEntityById(Object id);
}

public interface IFooDAO extends IGenericDAO<ExampleRequest> {
    public void flushDAO();
    public ExampleRequest getExampleRequestById(Long exampleRequestId);
}

@Stateless(name = "IFooDAO", mappedName = "IFooDAO")
public class FooDAO extends GenericDAO<ExampleRequest> implements IFooDAO {
    public FooDAO() {
        super(ExampleRequest.class);
    }

    @Override
    public void flushDAO(){
        em.flush();
    }

    @Override
    public ExampleRequest getExampleRequestById(Long exampleRequestId){
        String sql = "...";
        Query query = em.createNativeQuery(sql, ExampleRequest.class);
        //...
    }
}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题