Mapeamento Hibernate Annotation com Id sendo um objeto

[color=red]TÓPICO ENCERADO[/color]

Olá galera, estou fazendo um mapeamento com hibernate annotations usando o id não como sendo um tipo primitivo, mas sim uma classe:
//=============
//classe mapeada
[color=blue]@Entity
public class Carro implements Serializable {
@Id
PKLong pk = new PKLong();
private String marca;[/color]
//-----------------------
//classe que armazena o pk
[color=blue]public class PKLong implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long codigo;[/color]
//=============
no banco, quando eu faço a persistência de um Carro o campo id da tabela é uma string enorme, acredito que seja a clase PKLong serializada:
[color=blue]ac ed 00 05 73 72 00 0f 62 65 61 6e 73 2e 70 6b 2e 50 4b 4c 6f 6e 67 7b 6f f1 19 58 39 22 86 02 00 01 4a 00 06 63 6f 64 69 67 6f 78 70 00 00 00 00 00 00 00 00[/color]

a minha pergunta é a seguinte:
como o hibernate lida internamente com uma id que é um objeto?
Como eu posso estar recuperando essa classe? antes eu fazia isso por um número (1, 2, 3, …), mas e agora?

A primeira coisa que você tem que fazer é descobrir/decidir o que diabos é esse seu campo ID :slight_smile:

Você está falando que é uma String enorme, certo? E tá com cara mesmo de ser algum tipo de GUID.

Se for isso, porque você ao invés de tratá-lo como um objeto simplesmente não o trata como uma String?

Para o usuário buscar por um id numérico correspondente ao Carro que ele quer buscar é fácil? Mas como eu vou pedir a ele toda essa string?

Pergunta: porque diabos um usuário iria querer buscar por um ID de carro (ainda mais um ID desses)?

Para mim parece mais razoável que ele busque pelo nome, modelo, cor, ou qualquer outro tipo de coisa mas não o ID. Idealmente isso nem deveria aparecer para o usuário.

E finalizando, usar um ID desse tipo para uma tabela de “carros” me parece totalmente inadequado.

Alessandro,

         Só acho necessário o uso de um objeto representando uma chave primária, quando se refere a uma chave composta, até porque o id do carro será 'codigo' que é um tipo primitivo, mais você deve ter seus motivos de querer utilizar essa classe que representa o id de carro, acho que a solução é a mesma de chave composta.
  1. A classe Carro não é obrigada a implementar Serializable, só a classe PKLong;

  2. Isso aqui: “PKLong pk = new PKLong()” tá estranho, vamos colocar “private PKLong pk”;

  3. Substituir o annotation @Id por @EmbeddedId, na declaração do atributo pk na classe carro, indicando assim que a chave estará na classe PKLong;

  4. Adicionar o annotation @Embeddable, na classe PKLong, indicando assim que a classe PKLong representará uma chave;

  5. Retirar o annotation @Id do atributo código na classe PKLongn, pois isso está sendo feito no item 4;

         Satisfazendo as observações descritas acima, o código ficaria assim:
    

//-----------------------
//classe mapeada
[color=blue]@Entity
public class Carro {

@EmbeddedId
private PKLong pk;
private String marca;[/color]

//classe que armazena o pk
[color=blue]@Embeddable
public class PKLong implements Serializable {

@GeneratedValue(strategy=GenerationType.IDENTITY)
private long codigo;[/color]

//-----------------------

  Espero que funcione, mais acho que você deve analisar bem se é realmente necessário o uso de uma classe, para representar um único atributo primitivo.

Obrigado, vou testar e ver se isso funciona.

O que eu quero com isso é o seguinte:

Hoje eu estou usando o banco de dados Derby, futuramente (depois que o programa for instalado) irei usar mySql, sei que ambos aceitam a estratégia IDENTITY como generator de primaryKey, porém se algum dia um banco não suportar eu terei que dar manutenção em todos os meus pojo/bean? Por esse motivo eu estou querendo tirar essa anotação para uma única classe, mas como fazer isso com anotações?

Já procurei na documentação do hibernate e não encontrei nada.

a alternativa acima foi uma das soluções que encontrei, mas estou com problemas. alguém conheçe outra.

quanto ao recuperar por id, recupero por ele por que é assim que o hibernate.session busca um registro no banco:

[color=blue]import org.hibernate.Session;

public Carro recuperar(Long id) {
return (Carro) this.session.load(this.persistenceClass, id);
}
…[/color]

obrigado pelas idéias propostas até agora, até hoje a noite eu divulgo o resultado do código do jonatascp

Basta você criar uma superclasse com o seu Id anotado e usar a anotação @MappedSuperclass nessa classe.

mas com essa anotação eu poderei ter mapeamento na superclasse e também na subclasse? pois minha intenção é colocar somente a anotação do id nessa superclasse.

Você pode fazer isso:

@MappedSuperclass
public abstract class Carro {

    @Id
    private Long id;

    ...

}

@Entity
public class Fusca extends Carro {

    // Demais campos específicos da classe

}

J2Alex, nesse caso as duas classes devem implementar seralizable e estarem mapeadas, estou certo?
vou testar hj a noite e posto o resultado.

obrigado

Blz, deu certo, muito obrigado J2Alex.

Se eu tiver mais de uma classe extendendo de PKLong, no banco, vai ter um generator pra cada classe ou vai ser um só para todas as classes?

bom, deixa eu testar, já pedi demais nesse post.

posto o resultado a seguir.

Uhuuu, para cada classe um generator.

Muito obrigado,
[color=red]
TÓPICO ENCERADO[/color]