Persistir dados no Hibernate

3 respostas
S

Sou iniciante e estou com a seguinte dúvida, tenho duas classes sendo uma Produto e outra Categoria , no formulário do produto tenho um dropmenu onde seleciono a categoria , o problema é que não estou conseguindo perssistir a informação da “category_id”, estou usando o Hibernate e VHaptor3.

Olhando o DB o hibernate criou uma coluna category_id na tabela Product

Models

@javax.persistence.Entity
public class Product extends Entity {
	
	private String name;
	private Double value;
	
	
	
	 
	public void setName(String name) {
		this.name = name;
	}
	
	@NotEmpty
	@Length(min=5,max=100)
	public String getName() {
		return name;
	}
		

	public void setValue(Double value) {
		this.value = value;
	}
	

	public Double getValue() {
		return value;
	}

	@ManyToOne
	@JoinColumn(name="category_id")
	private Category category;
	
	
	
}
@javax.persistence.Entity
public class Category extends Entity {
	
	private String name;
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}

	@OneToMany(mappedBy = "category", targetEntity = Product.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	 private List<Product> products;
	
}

Controllers

@Resource
public class ProductController {

	private final Result result;
	private final ProductRepository repository;
	private final CategoryRepository cat_repository;
	private final Validator validator;
	
	ProductController(Result result, ProductRepository repository, CategoryRepository cat_repository, Validator validator) {
		this.result = result;
		this.repository = repository;
		this.cat_repository = cat_repository;
		this.validator = validator;
	}
	
	@Get("/products")
	public List<Product> index() {
		
		return repository.findAll();
		
	}
	
	
	@Post("/products")
	public void create(final Product product) {

		if (product.getName().isEmpty()) {
	        validator.add(new ValidationMessage("Nome não preenchido", "erro"));  
	    }

		if (product.getName().length() >= 10) {
	        validator.add(new ValidationMessage("Não deve conter mais de 10 caracteres", "erro"));  
	    }
		
		validator.validate(product);
		validator.onErrorUsePageOf(this).newProduct();
		repository.create(product);
		result.redirectTo(this).index();
	}
	
	
	@Get("/products/new")
	public Product newProduct() {  
		 result.include("categories", cat_repository.findAll());
		 return new Product();	 
	}
	

	
	@Put("/products")
	public void update(Product product) {
		validator.validate(product);
		validator.onErrorUsePageOf(this).edit(product);
		repository.update(product);
		result.redirectTo(this).index();
	}
	
	@Get("/products/{product.id}/edit")
	public Product edit(Product product) {
		result.include("categories", cat_repository.findAll());
		return repository.find(product.getId());
	}

	@Get("/products/{product.id}")
	public Product show(Product product) {
		return repository.find(product.getId());
	}

	@Delete("/products/{product.id}")
	public void destroy(Product product) {
		repository.destroy(repository.find(product.getId()));
		result.redirectTo(this).index();  
	}
}

View

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

	<div class="field">
		Name:<br />
		<input type="text" name="product.name" value="${product.name}"/>
	</div>
	
	<div class="field">
		Value:<br />
		<input type="text" name="product.value" value="${product.value}"/>
	</div>
	
	<div class="field">
	  <select name="category" id="category">
	    <c:forEach items="${categories}" var="category">
	      <option value="${category.id}" >${category.name}</option>
	    </c:forEach>
	  </select>	
    </div>

<div class="actions">
	<button type="submit" class='uibutton'>Salvar</button>
	</div>
</form>

<a href="${pageContext.request.contextPath}/products" class='uibutton'>Voltar</a>

Já tentei usar “” e mas nada, é necessário criar um metodo de acesso no Model Product para category_id ?

Outra dúvida , gostaria de selecionar o valor no menulist quando abrir um registro para atualizar qual atributo utilizo para selecionar o dropmenu? o exemplo abaixo não funciona…

<div class="field">
	  <select name="category_id" id="category_id">
	    <c:forEach items="${categories}" var="category">
	      <option value="${category.id}" <c:if test="${category.id==product}" >selected</c:if> >${category.name}</option>
	    </c:forEach>
	  </select>	
    </div>

Agradeço a ajuda

3 Respostas

S

Descobri onde estava errando:

Primeiro faltavam os metodos de acesso nos models

@javax.persistence.Entity
public class Product extends Entity {
	
	private String name;
	private Double value;

	
	
		 
	public void setName(String name) {
		this.name = name;
	}
	
	@NotEmpty
	@Length(min=5,max=100)
	public String getName() {
		return name;
	}
		

	public void setValue(Double value) {
		this.value = value;
	}
	

	public Double getValue() {
		return value;
	}


	public Category getCategory() {
		return category;
	}

	public void setCategory(Category category) {
		this.category = category;
	}


	@ManyToOne
	@JoinColumn(name="category_id")
	private Category category;
	
	
	
}
@javax.persistence.Entity
public class Category extends Entity {
	
	private String name;
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}

	public List<Product> getProducts() {
		return products;
	}

	public void setProducts(List<Product> products) {
		this.products = products;
	}

	@OneToMany(mappedBy = "category", targetEntity = Product.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	 private List<Product> products;
	
}

Na view ficou assim

[code]






Name:
Value:

Voltar

[code]

Agora está funcionando certinho, fica ai se alguém estiver iniciando como eu.....

otOtavio

me corrija se estiver errado, mas da maneira que esta implementado não necessita do List na classe categoria.

a não ser que tenha uma tela que insira na categoria os produtos dela.

S

Tem razão, vou retirar, Tks

[RESOLVIDO]

Criado 31 de julho de 2012
Ultima resposta 1 de ago. de 2012
Respostas 3
Participantes 2