Vraptor Logica com ManyToOne

11 respostas
macspace

Olá pessoal, estou com dificuldades em realizar um relacionamento ManyToOne, segue abaixo minhas classes:

A tabela aparelho possue um campo mar_codigo que esta relacionado com o campo id da tabela marca

tabela MARCA:

@Entity
@Table(name="marca")
@SequenceGenerator(name = "seqMarca", sequenceName = "seq_marca")
public class MarcaBean extends VisaoTIBean {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "seqMarca")
	@Column(name="id")
	private Integer id;
	
	@Column(name="mar_descricao")
	private String descricao;
}

Tabela APARELHO

@Entity
@Table(name="aparelho")
@SequenceGenerator(name = "seqAparelho", sequenceName = "seq_aparelho")
public class AparelhoBean extends VisaoTIBean {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "seqAparelho")
	@Column(name="id")
	private Integer id;
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name="mar_codigo", referencedColumnName="id")
	private MarcaBean marca;
	
	@Column(name="apa_modelo")
	private String modelo;
	
	@Column(name="apa_descricao")
	private String descricao;
	
	@Column(name="apa_especificacao")
	private String especificacao;
}

Lógica MARCA:

@Component
@InterceptedBy({LoginInterceptor.class, DaoInterceptor.class})
public class MarcaLogic {
	
	private final DaoFactory daoFactory;
	private final VisaoTILogic logic;
	
	@Parameter
	@Out
	private MarcaBean marca = new MarcaBean();
	
	@Parameter
	private List<MarcaBean> marcas;
		
	public MarcaLogic(DaoFactory daoFactory) {
		this.daoFactory = daoFactory;
		logic = new VisaoTILogic(daoFactory, MarcaBean.class);
	}
	
	public void edit(MarcaBean marca) {
		this.marca = (MarcaBean) logic.get(this.marca.getId());
	}
	
	@SuppressWarnings("unchecked")
	public void post() {
		if (marca.getId() == null)
			logic.insert(marca);
		else
			logic.update(marca);
	}
	
	public void delete(@Parameter(key="codigo") String codigo) {
		marca = new MarcaBean();
		marca.setId(Integer.parseInt(codigo));
		logic.delete(marca);
	}

	public void loadAll() {
		marcas = logic.loadAll();
	}
	
	public void loadAll(@Parameter(key="fieldOrder") String fieldOrder) {
		marcas = logic.loadAll(fieldOrder);
	}
	
	public void formulario() {
	}

	public List<MarcaBean> getMarcas() {
		return marcas;
	}	
}

Lógica APARELHO:

@Component
@InterceptedBy({LoginInterceptor.class, DaoInterceptor.class})
public class AparelhoLogic {
	
	private final DaoFactory daoFactory;
	private final VisaoTILogic logic;
	private final MarcaLogic logicMarca;
	
	@Parameter
	@Out
	private AparelhoBean aparelho = new AparelhoBean();
	
	@Parameter
	private List<AparelhoBean> aparelhos;

	private List<MarcaBean> marcas;
	
	public AparelhoLogic(DaoFactory daoFactory) {
		this.daoFactory = daoFactory;
		logic = new VisaoTILogic(daoFactory, AparelhoBean.class);
		logicMarca = new MarcaLogic(daoFactory);
		logicMarca.loadAll("descricao");
		marcas = logicMarca.getMarcas();
	}
	
	public void edit(AparelhoBean aparelho) {
		this.aparelho = (AparelhoBean) logic.get(this.aparelho.getId());
	}
	
	@SuppressWarnings("unchecked")
	public void post() {
		if (aparelho.getId() == null)
			logic.insert(aparelho);
		else
			logic.update(aparelho);
	}
	
	public void delete(@Parameter(key="codigo") String codigo) {
		aparelho = new AparelhoBean();
		aparelho.setId(Integer.parseInt(codigo));
		logic.delete(aparelho);
	}

	public void loadAll(@Parameter() {
		aparelhos = logic.loadAll();
	}
	
	public void formulario() {
	}

	public List<AparelhoBean> getAparelhos() {
		return aparelhos;
	}
	
	public List<MarcaBean> getMarcas() {
		return marcas;
	}
}

JSP da adição do APARELHO:

<body>
<h1>Novo Aparelho</h1>
<form action='aparelho.post.logic' method="post" accept-charset="iso-8859-1" id="formprincipal">
  Código: <input type="text" name="aparelho.id" value="${aparelho.id}" readonly="true"/><br/>
  Marca:
  <select name="aparelho.marca.id">
    <c:forEach var="m" items="${marcas}">
      <option value="${m.id}">${m.descricao}</option>
    </c:forEach>
  </select><br/>
  Modelo: <input type="text" name="aparelho.modelo" value="${aparelho.modelo}"/><br/>
  Descrição: <input type="text" name="aparelho.descricao" value="${aparelho.descricao}"/><br/>
  <input type="submit" value="confirmar"/>
</form>
</body>

Porém quando confirmo a inclusão de um novo aparelho, a marca sempre vem nula!!!

Alguém sabe me dize o que esta errado ???

[]'s
Márcio

11 Respostas

Lucas_Cavalcanti

existem os métodos:

aparelho.getMarca()

aparelho.setMarca()

marca.setId()

marca.getId()

?
T

só a Marca que ta vindo nulo??? vc tb precisa dos métodos Get e Set.

macspace

Existe todos os métodos gets e sets das classes aparelho e marca!!!

e somente a marca que esta vindo nulo, o resto dos campos esta vindo normalmente!!!

macspace

Alguém ai sabe ???

[]'s
márcio

Paulo_Silveira

posta pra gente as duas classes inteiras? do aparelho e da marca?
voce poderia tambem ativar o log de debug do vraptor que ele vai dizer examente que atributo ele esta tentando setar com qual variavel

macspace

AparelhoBean

@Entity
@Table(name="aparelho")
@SequenceGenerator(name = "seqAparelho", sequenceName = "seq_aparelho")
public class AparelhoBean extends VisaoTIBean {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "seqAparelho")
	@Column(name="id")
	private Integer id;
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name="mar_codigo", referencedColumnName="id")
	private MarcaBean marca;
	
	@Column(name="apa_modelo")
	private String modelo;
	
	@Column(name="apa_descricao")
	private String descricao;
	
	@Column(name="apa_especificacao")
	private String especificacao;
	
	@Override
	public String toString() {
		StringBuilder ret = new StringBuilder();
		return ret.append(id).append(" - ").append(descricao).toString();
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public MarcaBean getMarca() {
		return marca;
	}

	public void setMarca(MarcaBean marca) {
		this.marca = marca;
	}

	public String getModelo() {
		return modelo;
	}

	public void setModelo(String modelo) {
		this.modelo = modelo;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public String getEspecificacao() {
		return especificacao;
	}

	public void setEspecificacao(String especificacao) {
		this.especificacao = especificacao;
	}
}

MarcaBean

@Entity
@Table(name="aparelho")
@SequenceGenerator(name = "seqAparelho", sequenceName = "seq_aparelho")
public class AparelhoBean extends VisaoTIBean {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "seqAparelho")
	@Column(name="id")
	private Integer id;
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name="mar_codigo", referencedColumnName="id")
	private MarcaBean marca;
	
	@Column(name="apa_modelo")
	private String modelo;
	
	@Column(name="apa_descricao")
	private String descricao;
	
	@Column(name="apa_especificacao")
	private String especificacao;
	
	@Override
	public String toString() {
		StringBuilder ret = new StringBuilder();
		return ret.append(id).append(" - ").append(descricao).toString();
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public MarcaBean getMarca() {
		return marca;
	}

	public void setMarca(MarcaBean marca) {
		this.marca = marca;
	}

	public String getModelo() {
		return modelo;
	}

	public void setModelo(String modelo) {
		this.modelo = modelo;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public String getEspecificacao() {
		return especificacao;
	}

	public void setEspecificacao(String especificacao) {
		this.especificacao = especificacao;
	}
}

AparelhoLogic

@Component
@InterceptedBy({LoginInterceptor.class, DaoInterceptor.class})
public class AparelhoLogic {
	
	private final DaoFactory daoFactory;
	private final VisaoTILogic logic;
	private final MarcaLogic logicMarca;
	
	@Parameter
	@Out
	private AparelhoBean aparelho = new AparelhoBean();
	
	@Parameter
	private List<AparelhoBean> aparelhos;

	private List<MarcaBean> marcas;
	
	public AparelhoLogic(DaoFactory daoFactory) {
		this.daoFactory = daoFactory;
		logic = new VisaoTILogic(daoFactory, AparelhoBean.class);
		logicMarca = new MarcaLogic(daoFactory);
		logicMarca.loadAll("descricao");
		marcas = logicMarca.getMarcas();
	}
	
	public void edit(AparelhoBean aparelho) {
		this.aparelho = (AparelhoBean) logic.get(this.aparelho.getId());
	}
	
	@SuppressWarnings("unchecked")
	public void post() {
		if (aparelho.getId() == null)
			logic.insert(aparelho);
		else
			logic.update(aparelho);
	}
	
	public void delete(@Parameter(key="codigo") String codigo) {
		aparelho = new AparelhoBean();
		aparelho.setId(Integer.parseInt(codigo));
		logic.delete(aparelho);
	}

	public void formulario() {
	}

	public List<AparelhoBean> getAparelhos() {
		return aparelhos;
	}
	
	public List<MarcaBean> getMarcas() {
		return marcas;
	}	
}

MarcaLogic

@Component
@InterceptedBy({LoginInterceptor.class, DaoInterceptor.class})
public class MarcaLogic {
	
	private final DaoFactory daoFactory;
	private final VisaoTILogic logic;
	
	@Parameter
	@Out
	private MarcaBean marca = new MarcaBean();
	
	@Parameter
	private List<MarcaBean> marcas;
	
	public MarcaLogic(DaoFactory daoFactory) {
		this.daoFactory = daoFactory;
		logic = new VisaoTILogic(daoFactory, MarcaBean.class);
	}
	
	public void edit(MarcaBean marca) {
		this.marca = (MarcaBean) logic.get(this.marca.getId());
	}
	
	@SuppressWarnings("unchecked")
	public void post() {
		if (marca.getId() == null)
			logic.insert(marca);
		else
			logic.update(marca);
	}
	
	public void delete(@Parameter(key="codigo") String codigo) {
		marca = new MarcaBean();
		marca.setId(Integer.parseInt(codigo));
		logic.delete(marca);
	}

	public void formulario() {
	}

	public List<MarcaBean> getMarcas() {
		return marcas;
	}
}

aparelho.formulario.ok.js

<%@ page pageEncoding="iso-8859-1" language="java" contentType="text/html; charset=iso-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="css/default.css"/>
<script type="text/javascript" src="script/jquery-1.3.2.js"></script>
<script type="text/javascript" src="script/jquery.form.js"></script>
<script type="text/javascript" src="script/funcoes.js"></script>
<title>Dados Aparelho</title>
</head>
<body>
<h1>Novo Aparelho</h1>
<form action='aparelho.post.logic' method="post" accept-charset="iso-8859-1" id="formprincipal">
  Código: <input type="text" name="aparelho.id" value="${aparelho.id}" readonly="true"/><br/>
  Marca:
  <select name="aparelho.marca.id">
    <c:forEach var="m" items="${marcas}">
      <option value="${m.id}">${m.descricao}</option>
    </c:forEach>
  </select><br/>
  Modelo: <input type="text" name="aparelho.modelo" value="${aparelho.modelo}"/><br/>
  Descrição: <input type="text" name="aparelho.descricao" value="${aparelho.descricao}"/><br/>
  <input type="submit" value="confirmar"/>
  <c:if test="${aparelho.id != null}">
    <input type="button" value="excluir" onclick="deleteId('aparelho.delete.logic', ${aparelho.id});"/>
  </c:if>
</form>
</body>
</html>

sobre o log, eu criei o arquivo log4j.xml no src do meu projeto, porém tambem existe o log4j.properties com configurações do hibernate, e as únicas mensagens que são mostradas são de debug do hibernate

log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

	<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %5p [%-20c{1}] %m%n" />
		</layout>
	</appender>

	<category name="org.vraptor">
		<priority value="ERROR" />
		<appender-ref ref="stdout" />
	</category>
</log4j:configuration>

log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=warn, stdout

#log4j.logger.org.hibernate=info
log4j.logger.org.hibernate=debug

### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug

### log just the SQL
#log4j.logger.org.hibernate.SQL=debug

### log JDBC bind parameters ###
log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug

### log schema export/update ###
log4j.logger.org.hibernate.tool.hbm2ddl=debug

### log HQL parse trees
#log4j.logger.org.hibernate.hql=debug

### log cache activity ###
#log4j.logger.org.hibernate.cache=debug

### log transaction activity
#log4j.logger.org.hibernate.transaction=debug

### log JDBC resource acquisition
#log4j.logger.org.hibernate.jdbc=debug

### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace
macspace

Alguém???

Lucas_Cavalcanti

ve se no html gerado ele tá colocando o value dos options direitinho…

se estiver, troca o método do form pra GET e posta aqui a url que ele gerou no browser
pra ver se ta indo tudo direitinho

macspace

olá lucascs,

com o método POST no form, ele gera a seguinte url: aparelho.post.logic

ai troquei para o GET e ele gerou a seguinte url: aparelho.post.logic?aparelho.id=&aparelho.marca.id=3&aparelho.modelo=teste+123&aparelho.descricao=teste+lg

porém mesmo assim, continua o erro!!

Eu habilitei o log do vraptor, segue abaixo os eventos ocorridos após o submit do form:

09:22:57,474 DEBUG [VRaptorServlet      ] new request to /estacaotim/aparelho.post.logic
09:22:57,474 DEBUG [DefaultLogicLocator ] Requested url (request wrapped): /estacaotim/aparelho.post.logic
09:22:57,474 DEBUG [DefaultLogicLocator ] requested uri: aparelho.post.logic
09:22:57,474 DEBUG [DefaultLogicLocator ] logic method extracted: org.vraptor.component.DefaultLogicMethod@9e4585
09:22:57,474 DEBUG [VRaptorExecution    ] Calling execute on org.vraptor.core.WebRequest@e62121 / org.vraptor.component.DefaultLogicMethod@9e4585
09:22:57,474 DEBUG [DefaultViewLocator  ] Requested url (request wrapped): /estacaotim/aparelho.post.logic
09:22:57,474 DEBUG [DefaultViewLocator  ] requested uri: aparelho.post.logic
09:22:57,474 DEBUG [InterceptorsLogicFlow] Calling interceptor: org.vraptor.interceptor.RegisterAttributesInteceptor@8917a2
09:22:57,475 DEBUG [InterceptorsLogicFlow] Calling interceptor: org.vraptor.interceptor.FlashScopeInterceptor@6e9e64
09:22:57,475 DEBUG [InterceptorDealer   ] Adding interceptor br.com.visaoti.estacaotim.logic.LoginInterceptor
09:22:57,475 DEBUG [BasicIntrospector   ] Injecting with key user from SESSION
09:22:57,475 DEBUG [InterceptorsLogicFlow] Calling interceptor: br.com.visaoti.estacaotim.logic.LoginInterceptor@60e390
09:22:57,475 DEBUG [InterceptorDealer   ] Adding interceptor br.com.visaoti.estacaotim.logic.DaoInterceptor
09:22:57,475 DEBUG [InterceptorsLogicFlow] Calling interceptor: br.com.visaoti.estacaotim.logic.DaoInterceptor@fc40ae
09:22:57,475 DEBUG [BasicIntrospector   ] Outjecting key br.com.visaoti.estacaotim.model.dao.DaoFactory at REQUEST
09:22:57,475 DEBUG [InterceptorDealer   ] Adding interceptor org.vraptor.interceptor.ComponentLookupInterceptor
09:22:57,475 DEBUG [InterceptorsLogicFlow] Calling interceptor: org.vraptor.interceptor.ComponentLookupInterceptor@fa706d
09:22:57,475 DEBUG [ComponentLookupInterceptor] Instantiating class br.com.visaoti.estacaotim.logic.cadastro.auxiliar.AparelhoLogic
09:22:57,477 DEBUG [InterceptorDealer   ] Adding interceptor org.vraptor.interceptor.InjectionInterceptor
09:22:57,477 DEBUG [InterceptorsLogicFlow] Calling interceptor: org.vraptor.interceptor.InjectionInterceptor@177060f
09:22:57,477 DEBUG [BasicIntrospector   ] Injecting with key pageSize from SESSION
09:22:57,478 DEBUG [BasicIntrospector   ] Injecting with key page from SESSION
09:22:57,478 DEBUG [BasicIntrospector   ] Injecting with key lastPage from SESSION
09:22:57,478 DEBUG [BasicIntrospector   ] Injecting with key firstPage from SESSION
09:22:57,478 DEBUG [InterceptorDealer   ] Adding interceptor org.vraptor.interceptor.SettingAndValidationInterceptor
09:22:57,478 DEBUG [InterceptorsLogicFlow] Calling interceptor: org.vraptor.interceptor.SettingAndValidationInterceptor@12ef4c6
09:22:57,478 DEBUG [BasicIntrospector   ] Parameter aparelho.descricao will be used on field aparelho
09:22:57,478 DEBUG [JPathExecutor       ] ready to use parameter [aparelho, descricao]
09:22:57,478 DEBUG [SimpleConverterManager] Found converter org.vraptor.converter.basic.StringConverter
09:22:57,479 DEBUG [BasicIntrospector   ] Parameter aparelho.id will be used on field aparelho
09:22:57,479 DEBUG [JPathExecutor       ] ready to use parameter [aparelho, id]
09:22:57,479 DEBUG [SimpleConverterManager] Found converter org.vraptor.converter.basic.SimpleIntegerConverter
09:22:57,479 DEBUG [BasicIntrospector   ] Parameter aparelho.marca.id will be used on field aparelho
09:22:57,479 DEBUG [BasicIntrospector   ] Parameter aparelho.modelo will be used on field aparelho
09:22:57,479 DEBUG [JPathExecutor       ] ready to use parameter [aparelho, modelo]
09:22:57,479 DEBUG [SimpleConverterManager] Found converter org.vraptor.converter.basic.StringConverter
09:22:57,479 DEBUG [ValidatorEngine     ] checking validation using org.vraptor.component.DefaultLogicMethod
09:22:57,480 DEBUG [ValidatorEngine     ] loading resource bundle: messages for locale pt_BR
09:22:57,480 DEBUG [ValidatorEngine     ] Resource bundle not found: messages
09:22:57,480 DEBUG [InterceptorDealer   ] Adding interceptor org.vraptor.interceptor.ExecuteLogicInterceptor
09:22:57,480 DEBUG [InterceptorsLogicFlow] Calling interceptor: org.vraptor.interceptor.ExecuteLogicInterceptor@1c81ac0
09:22:57,480 DEBUG [ExecuteLogicInterceptor] executing business logic org.vraptor.component.DefaultLogicMethod@9e4585
macspace

olá pessoal, acho que consegui resolver… rssss
seguinte, vou tentar explicar o que fiz…

eu baixei o fonte do vraptor e comecei a depurar a classe:
org.vraptor.introspector.BasicIntrospector no método: List readParameters(List parametersToRead, Object component, LogicRequest logicRequest, ConverterManager converterManager, Object[] methodParamObjects)

até que cheguei na classe:
org.vraptor.reflection.JPathExecutor no método: internalSet(String[] path, String completeValue, String[] arrayValue, ReadParameter read, Object object, int start)

e verifiquei que quando o vraptor tentava busca o objeto marca do bean aparelho, ele recebia um objeto null, e a variável read (ReadParameter), vem com o parametro mightCreate como false!

ai simplesmente fui no meu AparelhoBean e criei o objeto marca e começou a funcionar perfeitamente, segue abaixo meu bean do aparelho:

@Entity
@Table(name="aparelho")
@SequenceGenerator(name = "seqAparelho", sequenceName = "seq_aparelho")
public class AparelhoBean extends VisaoTIBean {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "seqAparelho")
	@Column(name="id")
	private Integer id;
	
	@ManyToOne
	@JoinColumn(name="mar_codigo", referencedColumnName="id")
	private MarcaBean marca = new MarcaBean(); // <<<<<< Aqui que eu fiz alteração, criando o MarcaBean
	
	@Column(name="apa_modelo")
	private String modelo;
	
	@Column(name="apa_descricao")
	private String descricao;
	
	@Column(name="apa_especificacao")
	private String especificacao;
	
	@Override
	public String toString() {
		StringBuilder ret = new StringBuilder();
		return ret.append(id).append(" - ").append(descricao).toString();
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public MarcaBean getMarca() {
		return marca;
	}

	public void setMarca(MarcaBean marca) {
		this.marca = marca;
	}

	public String getModelo() {
		return modelo;
	}

	public void setModelo(String modelo) {
		this.modelo = modelo;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public String getEspecificacao() {
		return especificacao;
	}

	public void setEspecificacao(String especificacao) {
		this.especificacao = especificacao;
	}
}

Agora o que não sei se é para ser assim mesmo, ou se o vraptor teria que criar o MarcaBean para mim!!!
De qualquer forma muito obrigado a todos pela ajuda!!!

[]'s
Márcio

Paulo_Silveira

foi corajoso em baixar o fonte e debugar com a biblioteca! valeu a ajuda!

creio que deveria ter vindo true, estranho

Criado 11 de setembro de 2009
Ultima resposta 17 de set. de 2009
Respostas 11
Participantes 4