Many To Many Hibernate

3 respostas
S

Olá, Tenho um modelo Level que tem um relacionamento ManyToMany para Modules, o relacionamento segue abaixo nos modelos e o Hibernate criou corretamente a tabela de relacionamento module_level:

Model Level

@ManyToMany(
	        cascade = {CascadeType.PERSIST, CascadeType.MERGE},
	        mappedBy = "levels",
	        targetEntity = Module.class
	    )
	private Collection <Module> modules;

   //Gets e Sets

Model Module

@ManyToMany(
		        targetEntity=Level.class,
		        cascade={CascadeType.PERSIST, CascadeType.MERGE}
		    )
		    @JoinTable(
		        name="module_level",
		        joinColumns=@JoinColumn(name="module_id"),
		        inverseJoinColumns=@JoinColumn(name="level_id")
		    )
	private Collection <Level> levels;

 //Gets e Sets

Controller Level

@Put("/levels")
	public void update(Level level) {
		validator.validate(level);
		validator.onErrorUsePageOf(this).edit(level);
		repository.update(level);
		result.redirectTo(this).index();
	}

Formulário Level

<form action="${pageContext.request.contextPath}/levels" method="post">
  
	<c:if test="${not empty level.id}">
		<input type="hidden" name="level.id" value="${level.id}"/>
		<input type="hidden" name="_method" value="put"/>
	</c:if>

	<div class="field">
		Description:<br />
		<input type="text" name="level.description" value="${level.description}"/>
	</div>
	
	<div class="field">
       <c:forEach items="${modules}" var="module">
	     <input type="checkbox" name="level.modules" value="${module.id}"> ${module.name}<br>
	   </c:forEach>
	</div>

<div class="actions">
	<button type="submit">send</button>
	</div>
</form>

A dúvida é, como devo fazer para conseguir persistir as informações dos módulos que estão relacionados aos níveis, alguém tem um exemplo completo?

Agradeço

3 Respostas

S

Encontrei uma maneira de solucionar o problema , não sei se foi a mais correta…

Meu Model ficou assim:

Level

@ManyToMany(
	        targetEntity=Module.class,
	        cascade={CascadeType.PERSIST, CascadeType.MERGE}
	    )
	    @JoinTable(
	        name="module_level",
	        joinColumns=@JoinColumn(name="level_id"),
	        inverseJoinColumns=@JoinColumn(name="module_id")
	    )	
	private List <Module> modules;

Module

@ManyToMany(
	        cascade = {CascadeType.PERSIST, CascadeType.MERGE},
	        mappedBy = "modules",
	        targetEntity = Level.class
	    )
	private List <Level> levels;

Minha View ( Formulário ):

<div class="field">
                    <c:forEach items="${modules}" var="module" varStatus = "i">
	     <input type="checkbox" name="moduleList[${i.index}].id"
	          value="${module.id}"> ${module.name}<br>
	   </c:forEach>
	</div>

E por último o controller LevelController.java

@Put("/levels")
      public void update(Level level, List<Module> moduleList) {
	
	level.setModules(moduleList);
	validator.validate(level);
	validator.onErrorUsePageOf(this).edit(level);
	repository.update(level);
	result.redirectTo(this).index();

      }

Bem assim os dados estão sendo persistidos corretamente no DB pelo Hibernate, fica ai a solução

[RESOLVIDO]

S

Somente uma correção, alterei o CascadeType para REFRESH, a tabela module estava sendo atualizada com o exemplo anterior… com a forma abaixo apenas a de junção será modificada.

@ManyToMany(
	        cascade = {CascadeType.REFRESH},
	        mappedBy = "modules",
	        targetEntity = Level.class
	    )
	private List <Level> levels;


	@ManyToMany(
	        targetEntity=Module.class,
	        cascade={CascadeType.REFRESH}
	    )
	    @JoinTable(
	        name="module_level",
	        joinColumns=@JoinColumn(name="level_id"),
	        inverseJoinColumns=@JoinColumn(name="module_id")
	    )	
	private List <Module> modules;
S

Faltou a view , para selecionar os checkbox´s ao carregar o form quando necessário:

<div class="field">
       <c:forEach items="${modulesList}" var="module" varStatus = "i">
           <input type="checkbox" name="moduleList[${i.index}].id" value="${module.id}" <c:if test="${level.modules.contains(module)}"> checked="checked" </c:if> > ${module.name}<br>
      </c:forEach>
</div>
Criado 6 de outubro de 2012
Ultima resposta 8 de out. de 2012
Respostas 3
Participantes 1