JPA Mapear fk tipo String

Olá galera, como eu faço pra mapear um campo do tipo String que irá referenciar outra tabela(FK)?
No caso a tabela referenciada teria que ficar como? Tenho que mapear o campo que eu quero referenciar como @Id correto?

se não me engano tem que usar o @JoinColumn também

    @Id
    @JoinColumn(name = "COLUNA_MINHA_TABELA", referencedColumnName = "COLUNA_OUTRA_TABELA", nullable = false)
    private String campo;

Não estou sabendo fazer isso, eu tenho as tabelas Usuario e GrupoAcesso, eu preciso que sempre que adicionar um Usuario adicione também um GrupoAcesso e o campo login da tabela GrupoAcesso referencie o campo login da tabela Usuario, da pra fazer isso?
Seguem meus códigos:

package com.modelo.bean;

import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.JoinColumn;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToOne;

@Entity
public class Usuario implements Serializable {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	protected Integer idUsuario;
	protected String login;
	protected String senha;
	@Column(length = 60)
	protected String nome;
	
	@OneToOne(cascade = CascadeType.PERSIST)
	@JoinColumn(name = "idContato")
	protected Contato contato = new Contato();
	
	@OneToOne(cascade = CascadeType.PERSIST)
	@JoinColumn(name = "idEndereco")
	protected Endereco endereco = new Endereco();
	
	@OneToOne(cascade = CascadeType.PERSIST)
	protected GrupoAcesso grupoAcesso = new GrupoAcesso();

	public Integer getIdUsuario() {
		return idUsuario;
	}

	public void setIdUsuario(Integer idUsuario) {
		this.idUsuario = idUsuario;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getSenha() {
		return senha;
	}

	public void setSenha(String senha) {
		this.senha = senha;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public Contato getContato() {
		return contato;
	}

	public void setContato(Contato contato) {
		this.contato = contato;
	}
	
	public GrupoAcesso getGrupoAcesso() {
		return grupoAcesso;
	}

	public void setGrupoAcesso(GrupoAcesso grupoAcesso) {
		this.grupoAcesso = grupoAcesso;
	}
	

	public Endereco getEndereco() {
		return endereco;
	}

	public void setEndereco(Endereco endereco) {
		this.endereco = endereco;
	}
}
package com.modelo.bean;

import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;

@Entity
public class GrupoAcesso implements Serializable {
	@JoinColumn(name="login", referencedColumnName="login")
	@OneToOne
	private String login = "zezin";
	
	@Id
	private String nomeGrupoAcesso;
	
	public GrupoAcesso(){
		
	}
	
	public String getNomeGrupoAcesso() {
		return nomeGrupoAcesso;
	}

	public void setNomeGrupoAcesso(String nomeGrupoAcesso) {
		this.nomeGrupoAcesso = nomeGrupoAcesso;
	}

}

Seu @JoinColumn referente ao GrupoAcesso tem que estar na sua entidade usuário

Mas de acordo com a especificação do JAAS eu preciso criar a referência a partir de um campo da tabela de acesso GrupoAcesso para a tabela de Usuario. Como fica agora?
Quem referencia é GrupoAcesso para Usuario "/

ta… você disse que sempre quando gravar um Usuario, quer que seja gravado um GrupoAcesso… portanto você tem que referenciar na sua entidade Usuario como isso deve ser feito… deve definir a coluna do banco e o CascadeType

@OneToOne(cascade = CascadeType.PERSIST)  
@JoinColumn(name="login", referencedColumnName="login") 
protected GrupoAcesso grupoAcesso = new GrupoAcesso(); 

se fosse pra gravar um Usuario sempre que um GrupoAcesso fosse gravado (o que não faz sentido), aí sim seria ao contrário

Então é isso mesmp, quando gravar um Usuario tem que gravar um GrupoAcesso, contudo a FK vem do GrupoAcesso pro Usuario sacou?

então…

na sua tabela Usuario você tem um campo LOGIN que é uma FK referente à tabela GrupoUsuario, certo?

[b]Usuario

idUsuario (PK)
login(varchar)
senha(varchar)
nome(varchar)
idContato (FK)
idEndereco (FK)
idGrupoAcesso (FK)[/b]

ou não é assim?

Não. Na tabela GrupoAcesso tenho uma FK que referencia o campo login do Usuario:

GrupoUsuario
nomeGrupoUsuario(varchar)
login(FK)

Usuario
login(varchar)

ta… então não vai dar certo hehehe

você não vai conseguir gravar um GrupoAcesso quando gravar o Usuario usando o Cascade se suas tabelas estão modeladas dessa maneira…

porque eu imagino que o Usuario é quem tem que ter a chave do GrupoAcesso ao qual ele pertence, e não o inverso…

Cara, eu fiz do jeito que deveria ser Usuario com FK pro GrupoAcesso e funcionou \o/
Tava viajando nessa, vlw pela ajuda ai :slight_smile:
Abraço!

Só maus uma dúvida, aqui:

package com.modelo.bean;

import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.JoinColumn;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToOne;

@Entity
public class Usuario implements Serializable {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	protected Integer idUsuario;
	protected String login;
	protected String senha;
	@Column(length = 60)
	protected String nome;
	
	@OneToOne(cascade = CascadeType.PERSIST)
	@JoinColumn(name = "idContato")
	protected Contato contato = new Contato();
	
	@OneToOne(cascade = CascadeType.PERSIST)
	@JoinColumn(name = "idEndereco")
	protected Endereco endereco = new Endereco();
	
	@OneToOne(cascade = CascadeType.PERSIST)
	@JoinColumn(name = "login")
	protected GrupoAcesso grupoAcesso = new GrupoAcesso();

	public Integer getIdUsuario() {
		return idUsuario;
	}

	public void setIdUsuario(Integer idUsuario) {
		this.idUsuario = idUsuario;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getSenha() {
		return senha;
	}

	public void setSenha(String senha) {
		this.senha = senha;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public Contato getContato() {
		return contato;
	}

	public void setContato(Contato contato) {
		this.contato = contato;
	}
	
	public GrupoAcesso getGrupoAcesso() {
		return grupoAcesso;
	}

	public void setGrupoAcesso(GrupoAcesso grupoAcesso) {
		this.grupoAcesso = grupoAcesso;
	}
	

	public Endereco getEndereco() {
		return endereco;
	}

	public void setEndereco(Endereco endereco) {
		this.endereco = endereco;
	}
}

Eu quero usar o campo login como FK tb, tem como? Deste jeito que eu fiz ta dando erro…

Sem problemas hehehe
essas coisas podem ser confusas mesmo

só altere o seu primeiro post desse tópico e adicione a tag [RESOLVIDO] no título do tópico :slight_smile:

Postei uma última dúvida ai :slight_smile:

que erro? posta aí

você não precisa dar os news nos atributos daquele jeito…

Ta dizendo que o campo “login” está repetido "/

com.sun.faces.mgbean.ManagedBeanCreationException: Não é possível criar instância para·a classe: com.modelo.managedBean.UsuarioMB.
	at com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:193)
	at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:102)
	at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:409)
	at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:269)
	at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
	at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
	at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
	at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
	at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:69)
	at org.apache.el.parser.AstValue.getValue(AstValue.java:112)
	at org.apache.el.parser.AstNot.getValue(AstNot.java:42)
	at org.apache.el.parser.AstAnd.getValue(AstAnd.java:37)
	at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
	at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
	at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
	at javax.faces.component.UIComponentBase.isRendered(UIComponentBase.java:413)
	at org.primefaces.component.menu.MenuRenderer.encodePlainMenuContent(MenuRenderer.java:118)
	at org.primefaces.component.menu.MenuRenderer.encodePlainSubmenu(MenuRenderer.java:159)
	at org.primefaces.component.menu.MenuRenderer.encodePlainMenuContent(MenuRenderer.java:128)
	at org.primefaces.component.menu.MenuRenderer.encodeMarkup(MenuRenderer.java:100)
	at org.primefaces.component.menu.BaseMenuRenderer.encodeEnd(BaseMenuRenderer.java:40)
	at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1786)
	at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
	at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782)
	at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402)
	at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
	at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:470)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Thread.java:722)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: TurismoGuiadoPU] Unable to build EntityManagerFactory
	at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:677)
	at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:126)
	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:51)
	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:33)
	at com.modelo.dao.UsuarioDAO.<init>(UsuarioDAO.java:18)
	at com.modelo.managedBean.UsuarioMB.<init>(UsuarioMB.java:19)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
	at java.lang.Class.newInstance0(Class.java:372)
	at java.lang.Class.newInstance(Class.java:325)
	at com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:188)
	... 49 more
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.modelo.bean.Usuario column: login (should be mapped with insert="false" update="false")
	at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:652)
	at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:674)
	at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:696)
	at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:450)
	at org.hibernate.mapping.RootClass.validate(RootClass.java:192)
	at org.hibernate.cfg.Configuration.validate(Configuration.java:1102)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1287)
	at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:859)
	at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)

mostra denovo suas classes Usuarios e GrupoAcesso, pra eu ver como elas estão agora…

Segue ai:

Usuario

package com.modelo.bean;

import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.JoinColumn;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToOne;

@Entity
public class Usuario implements Serializable {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	protected Integer idUsuario;
	protected String login;
	protected String senha;
	@Column(length = 60)
	protected String nome;
	
	@OneToOne(cascade = CascadeType.PERSIST)
	@JoinColumn(name = "idContato")
	protected Contato contato;
	
	@OneToOne(cascade = CascadeType.PERSIST)
	@JoinColumn(name = "idEndereco")
	protected Endereco endereco;
	
	@OneToOne(cascade = CascadeType.PERSIST)
	@JoinColumn(name = "login")
	protected GrupoAcesso grupoAcesso;

	public Integer getIdUsuario() {
		return idUsuario;
	}

	public void setIdUsuario(Integer idUsuario) {
		this.idUsuario = idUsuario;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getSenha() {
		return senha;
	}

	public void setSenha(String senha) {
		this.senha = senha;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public Contato getContato() {
		return contato;
	}

	public void setContato(Contato contato) {
		this.contato = contato;
	}
	
	public GrupoAcesso getGrupoAcesso() {
		return grupoAcesso;
	}

	public void setGrupoAcesso(GrupoAcesso grupoAcesso) {
		this.grupoAcesso = grupoAcesso;
	}
	

	public Endereco getEndereco() {
		return endereco;
	}

	public void setEndereco(Endereco endereco) {
		this.endereco = endereco;
	}
}

GrupoAcesso

package com.modelo.bean;

import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;

@Entity
public class GrupoAcesso implements Serializable {

	@Id
	private String login;
	private String nomeGrupoAcesso;

	public GrupoAcesso() {
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getNomeGrupoAcesso() {
		return nomeGrupoAcesso;
	}

	public void setNomeGrupoAcesso(String nomeGrupoAcesso) {
		this.nomeGrupoAcesso = nomeGrupoAcesso;
	}
}

adicione o (insertable = false e updatable = false) na sua anotação @JoinColumn

Ok. Resolveu =))
Estou com outro problema agora "/, tipo a pk da minha tabela GrupoAcesso será o login mesmo, pois ele não pode ser repetido tb, estou anotando ele assim:

@Entity
public class GrupoAcesso implements Serializable {

	@Id
	private String login";
	
	private String nomeGrupoAcesso = "promotor";
	

	public GrupoAcesso() {
	}

	public GrupoAcesso(String login) {
		this.login = login;
	}

ai ocorre este erro:

Erro: org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.modelo.bean.GrupoAcesso

Pois bem, como eu vou setar manualmente o campo login?
Tentei passar o atributo pro construtor na hora de instanciar a classe Usuario mas não rolou "/

	@OneToOne(cascade = CascadeType.PERSIST)
	@JoinColumn(name = "login", insertable=false, updatable=false)
	protected GrupoAcesso grupoAcesso = new GrupoAcesso(this.login);

Ve alguma saída?