Hibernate Lazy Load и @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;
}
}
В моем контроллере с помощью Named Query я пытаюсь получить все вакансии.
Метод контроллера 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
объект.
Чтобы игнорировать свойство, которое я слышал, чтобы использовать @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 игнорировать свойства, но все же требуется время, чтобы получить из спящего режима.