У меня есть сущность "Account", которая имеет отношение ManyToMany к сущности "Role".Когда я добавляю новую учетную запись через JSP Form, все работает нормально.Я могу выбрать там все роли, которые я хотел бы связать с учетной записью с помощью флажков.
Если я сейчас попытаюсь отредактировать добавленную учетную запись, я снова получу флажки для ролей, но ни одна из них не отмечена (проверять те, которые я проверял при добавлении учетной записи).
Я все отладил, и я понял, что адрес объекта Role, который загружается через account.getRoles (), не совпадает с адресом, загруженным через roleService.list ().Так что я думаю, что должна быть проблема с сеансом, но я понятия не имею, с чего мне начать поиск: S ...
Извлечение сущности счета:
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER)
@JoinTable(name = "Account_Role", joinColumns = {
@JoinColumn(name = "Account_id") },
inverseJoinColumns = { @JoinColumn(name = "Role_id") })
private Set<Role> roles = new HashSet<Role>(0);
Извлечение роли:
@Transactional
public List<Role> list() {
return roleDAO.list();
}
Извлечение роли DAO:
@Autowired
private SessionFactory sessionFactory;
@SuppressWarnings("unchecked")
public List<Role> list() {
return sessionFactory.getCurrentSession().createQuery("from Role").list();
}
Извлечение правки.jsp учетной записи
<tr>
<td style="width:75px">
<label for="roles"><spring:message code="labels.account.form.roles" text="Roles" /></label>
</td>
<td>
<form:checkboxes path="roles" items="${roleList}" itemLabel="name" itemValue="idAsString" delimiter="<br/>"/>
</td>
</tr>
Выписка из контроллера учетной записи
/**
* edit() - Save edited item
* @param id of changed object
* @param item which has been changed
* @return path to view
*/
@RequestMapping(value="/edit/{id}", method=RequestMethod.POST)
public String edit(@PathVariable("id") Long id, @ModelAttribute("item") Account item, BindingResult bindingResult, Model model) {
accountService.merge(item);
return "redirect:/account/list";
}
/**
* edit() - Edit an item
* @param id of item to change
* @param model to store item
* @return path to view
*/
@RequestMapping(value="/edit/{id}", method=RequestMethod.GET)
public String editForm(@PathVariable("id") Long id, Model model) {
Account item = accountService.load(id);
for(Role r : item.getRoles()){
System.out.println("ROLE ITEM: ID="+r.getId()+" | NAME="+r.getName()+" | HASH="+r);
}
for(Role r : roleService.list()){
System.out.println("ROLE SERVICE: ID="+r.getId()+" | NAME="+r.getName()+" | HASH="+r);
}
model.addAttribute("item", item);
model.addAttribute("roleList", roleService.list());
return "account/edit";
}
Выписка из spring-servlet.xml:
<!-- Activates various annotations to be detected in bean classes -->
<context:annotation-config />
<!-- Scans the classpath for annotated components that will be auto-registered as Spring beans -->
<context:component-scan base-package="fi.java.elearning.*" />
<!-- Configures the annotation-driven Spring MVC Controller programming model -->
<mvc:annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- Include Tiles for View Rendering -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass">
<value>
org.springframework.web.servlet.view.tiles2.TilesView
</value>
</property>
</bean>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/configurations/tiles/tiles.xml</value>
</list>
</property>
</bean>
<!-- multipart file resolver bean -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
<!-- multi language support -->
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="de" />
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="language" />
</bean>
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" >
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor" />
</list>
</property>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="languages/messages" />
</bean>
<!-- Import Hibernate Context -->
<import resource="configurations/hibernate/hibernate-context.xml" />
<!-- Import Spring Security -->
<import resource="configurations/spring/spring-security.xml" />
Извлечение из web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/views/contents/exceptions/404.jsp</location>
</error-page>
Извлечение из hibernate.context.xml:
<context:property-placeholder location="/WEB-INF/configurations/hibernate/database.properties" />
<!-- Declare the Hibernate SessionFactory for retrieving Hibernate sessions -->
<!-- See http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/orm/hibernate3/annotation/AnnotationSessionFactoryBean.html -->
<!-- See http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/SessionFactory.html -->
<!-- See http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/Session.html -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource"
p:configLocation="${hibernate.config}"
p:packagesToScan="fi.java.elearning"/>
<!-- Declare a datasource that has pooling capabilities-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"
p:driverClass="${app.jdbc.driverClassName}"
p:jdbcUrl="${app.jdbc.url}"
p:user="${app.jdbc.username}"
p:password="${app.jdbc.password}"
p:acquireIncrement="5"
p:idleConnectionTestPeriod="60"
p:maxPoolSize="100"
p:maxStatements="50"
p:minPoolSize="10" />
<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<!-- Enable annotation style of managing transactions -->
<tx:annotation-driven transaction-manager="transactionManager" />
System.out.println (), который я использовал в контроллере, показывает (насколько я думаю) проблему:
Выписка из консоли:
РОЛЬ ПУНКТ: ID = 1 |NAME = ACCOUNT_MANAGER |¬†HASH=fi.java.elearning.data.model.Role@9293709 РОЛЬ СЕРВИС: ID = 1 |NAME = ACCOUNT_MANAGER |¬†HASH=fi.java.elearning.data.model.Role@2721e92 РОЛЬ СЕРВИС: ID = 2 |NAME = Test |¬†HASH=fi.java.elearning.data.model.Role@1235047f
Таким образом, ITEM - это роль, которая была первоначально проверена при добавлении учетной записи.И этот должен быть уже проверен, когда я редактирую учетную запись.Но это не так.И я думаю, что это связано с другим адресом / ссылкой (9293709 / 2721e92).Если я добавлю @Transcational Annotation поверх действия контроллера, то ссылки будут правильными.Флажок затем проверяется.Но это не имеет смысла для меня.Аннотации транзакций должны быть в ServiceLayer, не так ли?
Большое спасибо за вашу помощь ...