Hibernate Lazy Load和@Transient

时间:2014-02-03 06:11:59

标签: java hibernate spring-mvc lazy-loading transient

我有一个Java Spring MVC控制器应用程序。它使用 hibernate 4和spring 3 。使用 Bitronix事务管理器

以下是我的一些模型类

User.java

    public class User  implements java.io.Serializable {

        private Integer userId;
        private String userName;
        private String emailId;
        private Set<Jobs> jobses = new HashSet<Jobs>(0);

        //getters and setters   

        @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="user")
        public Set<Jobs> getJobses() {
            return this.jobses;
        }

        public void setJobses(Set<Jobs> jobses) {
            this.jobses = jobses;
        }
    }

Jobs.java

@NamedQueries({
    @NamedQuery(
        name = "findJobsByUser",
        query = "from Jobs jobs where jobs.user = :user"
    )
})
@JsonIgnoreProperties("user")
@Entity
@Table(name="jobs"
    ,catalog="mydb"
)
public class Jobs  implements java.io.Serializable {

    private Integer jobId;
    private User user;
    private String jobName;
    private Set<Tasks> taskses = new HashSet<Tasks>(0);
    //getters & setters

    @Transient
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="UserId")
    public User getUser() {
        return this.user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="jobs")
    public Set<Tasks> getTaskses() {
        return this.taskses;
    }

    public void setTaskses(Set<Tasks> taskses) {
        this.taskses = taskses;
    }
}

Tasks.java

public class Tasks  implements java.io.Serializable {

    private Integer taskId;
    private Jobs jobs;
    private String taskName;
    private Set<Process> processes = new HashSet<Process>(0);

    //getters & setters

    @Transient
    @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
    @JoinColumn(name="JobId")
    public Jobs getJobs() {
        return this.jobs;
    }

    public void setJobs(Jobs jobs) {
        this.jobs = jobs;
    }

    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="tasks")
    public Set<Process> getProcesses() {
        return this.processes;
    }

    public void setProcesses(Set<Process> processes) {
        this.processes = processes;
    }
}

Process.java

public class Process  implements java.io.Serializable {

    private Integer processId;
    private Tasks tasks;
    private String processName;

    //getters and setters

    @Transient
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="TaskId")
    public Tasks getTasks() {
        return this.tasks;
    }

    public void setTasks(Tasks tasks) {
        this.tasks = tasks;
    }

}

在我的控制器中使用命名查询我试图获得所有工作。

JobsDetailsController.java控制器方法

@RequestMapping(value = "/jobsdeatils/{userId}", method = RequestMethod.GET)
@ResponseBody
public List<Jobs> jobsDetails(@PathVariable Integer userId) throws IOException {
    try {
        User user=userService.findById(userId);

        Map<String, Object> queryParams=new LinkedHashMap<String, Object>(); 

        queryParams.put("user", user);

        jobs=jobsService.findByNamedQuery("findJobsByUser", queryParams);

    } catch(Exception e) {
        logger.debug(e.getMessage());
    }
    return jobs;
}

我想要的是,当我检索List<Jobs>时,我想要任务,然后在内部任务中,我不希望hibernate为jobs对象设置值。而且在Process我也不想为tasks对象设置。

忽略我听到的使用this SO question中的@Transient的属性。

这是我的测试用例

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration("classpath:webapptest")
@ContextConfiguration(locations = {"classpath:test-applicationcontext.xml"})
public class FindJobsControllerTest {

private MockMvc springMvc;

    @Autowired
    WebApplicationContext wContext;

    @Before
    public void init() throws Exception {
        springMvc = MockMvcBuilders.webAppContextSetup(wContext).build();
    }

    @Test
    public void documentsPollingTest() throws Exception {
        ResultActions resultActions=springMvc.perform(MockMvcRequestBuilders.get("/jobsdeatils/2").accept(MediaType.APPLICATION_JSON));
        resultActions.andDo(MockMvcResultHandlers.print());
        resultActions.andExpect(MockMvcResultMatchers.status().isOk());
    }
}

但是当我开始测试时,我的异常为java.lang.IllegalStateException: Failed to load ApplicationContext

Folowing是追踪

Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.org.myapp.model.Jobs.user in com.org.myapp.model.User.jobses
    at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:708)
    at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:668)
    at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:66)
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1593)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1350)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1737)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1788)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:242)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:372)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:357)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1545)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1483)
    ... 65 more

为什么?我该如何解决?

我可以在没有@Transient的情况下尝试,但是对于大数据我需要等待很长时间以及JSON字符串我无法进入我的客户端应用程序。我正在使用JSON忽略属性,但仍需要时间从hibernate中检索。

0 个答案:

没有答案