[Resolvido] Hibernate - mapeando @OneToMany sem chave primaria

Estou migrando um sistema para Java e devido algumas particularidades do sistema preciso realizar um mapeamento sem a chave primaria.

Segue as classes abaixo:

@Entity
public class Ender {

	@EmbeddedId
	private EnderPk id;

	@Column(name = "DEVEDOR_NOME", length = 50)
	private String nome;
}
@Embeddable
public class EnderPk implements Serializable {

	private static final long serialVersionUID = 1L;

	@Column(name = "DEVEDOR_CPF", length = 15, nullable = false)
	private String cpf;

	@Column(name = "ENDER_FONTE", length = 1, nullable = false)
	private String fonte;

	@Column(name = "ENDER_NUMSEQ", nullable = false)
	private Long numSeq;
}
public class Devedor {

	@Id
	@GeneratedValue
	@Column(name = "devedor_codigo", nullable = false)
	private Long codigo;

	@OneToMany(mappedBy = "devedor")
	@Cascade(CascadeType.SAVE_UPDATE)
	@OrderBy(clause = "CONT_FLAGBAIXA")
	private List<Contrato> contratos = new ArrayList<Contrato>();


	/* Aqui esta a duvida, não tenho ideia se existe uma forma de criar
	 * essa List sem usar um atributo mapeado com chave nesta classe 
	 */
	@OneToMany(mappedBy = "EnderPk.cpf")
	@Cascade(CascadeType.SAVE_UPDATE)
	private List<Ender> enderecos = new ArrayList<Ender>();
}

Como faz pouco tempo que estou programando em java não sei se isso é possivel dessa forma que estou tentando ou existe outra forma de Criar essa List.

Obrigado!

Vc não quer usar a fk na outra ponta é isso? Basta não colocar o mappedBy. Com isso o hibernate vai enteder que esse é um novo relaciomento e vai criar uma tabela de relacionamento para tratar a inserção e atualização dos dados. Tem problema não.

Alberto

Acho, que não consegui me expresar direito no primeiro post, segue um exemplo mais detalhado do problema que estou enfrentando.
Na verdade nem sei se existe alguma forma de fazer esse mapeamento.

Tabelas no banco de dados:

    CREATE TABLE DEVEDOR (
           DEVEDOR_CODIGO    INTEGER NOT NULL,
           DEVEDOR_CPF           CHAR(15) NOT NULL,
           DEVEDOR_NOME        CHAR(50))
    ALTER TABLE DEVEDOR ADD PRIMARY KEY (DEVEDOR_CODIGO);
    CREATE TABLE TELEFONE (
           DEVEDOR_CPF             CHAR(15) NOT NULL,
           TELEFONE_TEL            CHAR(16) NOT NULL,
           TELEFONE_DDD            CHAR(5))
    ALTER TABLE TELEFONE ADD PRIMARY KEY (DEVEDOR_CPF, TELEFONE_TEL);
Devido a alguns problemas com volume de importação de registros no banco de dados que é realizado todo dia, tive que fazer algumas coisas um pouco "erradas" nesse sistema pra melhorar a velocidade de inserção no banco. Com isso passou a existir alguns relacionamentos entre tabelas com chaves cadidatas no lugar de chaves primarias como nesse caso que o relacionamento entre as tabelas é realizado pelo campo DEVEDOR_CPF no lugar da chave primaria DEVEDOR_CODIGO.

Ai que surge o problema eu não consegui criar uma List no bean do DEVEDOR com os telefones pois o relacionamento é feito atraves do DEVEDOR_CPF. não sei se isso é possivel, se alguem tiver alguma ideia de como fazer isso dá uma força.

Segue os Java Beans:

Obs: pra simplificar o exemplo eu desconsiderei a chave primaria composta na classe Telefone, assim como simplifiquei as tabelas no banco de dados.

@Entity
public class Telefone {

    @Column(name = "DEVEDOR_CPF", length = 15, nullable = false)
    private String cpf;

    @Column(name = "TELEFONE_TEL", length = 16, nullable = false)
    private String tel;

    @Column(name = "TELEFONE_DDD", length = 5)
    private String ddd;

    /* getters and setters */

}
@Entity
public class Devedor {

    @Id
    @GeneratedValue
    @Column(name = "devedor_codigo", nullable = false)
    private Long codigo;

    @Column(name = "devedor_cpf", length = 15, nullable = false)
    private String cpf;

    @Column(name = "devedor_nome", length = 50)
    private String nome;

    @OneToMany(mappedBy = "cpf")
    private List<Telefone> telefones = new ArrayList<Telefone>();

    /* getters and setters */

}
Obrigado,
Cesar

Primeiro: sua classe Telefone nao deve ter um “cpf”. Deve ter uma “Pessoa”, que vai ser uma ManyToOne :slight_smile:
Depois de fazer o ajuste acima (como um ManyToOne), voce pode usar a anotacao @JoinColumn para especificar como as colunas sao ligadas. Veja se da certo :slight_smile:

Então dessa forma, eu sei que dá certo! O problema é que essas tabelas são de um sistema em produção que estou migrado apenas parte dele p/ Web com o java, assim não posso alterar a estrutura das tabelas. Isso que esta complicando, agora não sei se existe alguma forma de fazer isso sem mexer nas tabelas essa é a duvida…

Valeu…

Mas eu nao sugeri que mudasse o banco de dados :slight_smile: Sugeri que mudasse apenas seu codigo Java…

Então, mas é isso mesmo que eu não queria fazer… rs… pois o Id da Entity!

Bom consegui resolver o problema aqui de outra forma, atraves do Controller , mas agreço sua ajuda!

ficou assim:


@Entity
public class Devedor {

	@Id
	@GeneratedValue
	@Column(name = "devedor_codigo", nullable = false)
	private Long codigo;

	@Column(name = "devedor_cpf", length = 15, nullable = false)
	private String cpf;

	@Column(name = "devedor_nome", length = 50)
	private String nome;

	@Transient
	private List<Telefone> telefones = new ArrayList<Telefone>();
   
}

@Post
@Path("/buscaDevedor")
public Devedor mostraDevedor(Long codigo) {
      Devedor devedor = dao.carrega(codigo);
      if (devedor == null) {
	  validator.add(new ValidationMessage("Devedor não Localizado!","devedor.codigo"));
      }

      validator.onErrorUse(Results.page()).of(DevedoresController.class).buscaDevedor();


      /* busca os telefones por cpf */
      devedor.setTelefones(daoTel.busca(devedor.getCpf()));
	
      return devedor;
}

Obrigado pela força!!!

Bom que funcionou :slight_smile: Mas eu estava sugerindo algo assim:

@Entity  
public class Telefone {  
  
    @Column(name = "DEVEDOR_CPF", length = 15, nullable = false)  
    @ManyToOne
    @JoinColumn(name="DEVEDOR_CPF", referencedColumnName="devedor_cpf")
    private Devedor devedor;  
  
    @Column(name = "TELEFONE_TEL", length = 16, nullable = false)  
    private String tel;  
}  


@Entity  
public class Devedor {  
  
    @Id  
    @GeneratedValue  
    @Column(name = "devedor_codigo", nullable = false)  
    private Long codigo;  
  
    @Column(name = "devedor_cpf", length = 15, nullable = false)  
    private String cpf;  
  
    @Column(name = "devedor_nome", length = 50)  
    private String nome;  
  
    @OneToMany(mappedBy = "devedor")  
    private List<Telefone> telefones = new ArrayList<Telefone>();  
  
}  

Hum… entendi vou tentar isso tambem, por curiosidade!

Obrigado!!!