Pergunta

Estou tendo um problema ao consultar uma entidade que possui relacionamento OneToOne com outra.Este é o cenário:

Tabelas de banco de dados:

create table people (
    id decimal(10,0) NOT NULL,
    email varchar(512) NOT NULL
);

create table users (
    email varchar(512) NOT NULL
);

Dados de teste:

insert into users (email) values ('jhon@domain.com');
insert into users (email) values ('mary@domain.com');

insert into people (id, email) values (1, 'jhon@domain.com');
insert into people (id, email) values (2, 'mary@domain.com');

Entidades:

@Entity(name = "people")
public class Person implements Serializable {

    @Column
    @Id
    private long id;

    @Column
    private String email;

    public long getId() {
        return id;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

@Entity(name = "tbl_users")
public class User implements Serializable {

    @Id
    private String email;

    @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinColumn(name = "email", referencedColumnName = "email")
    private Person person;

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

Invocação:

...
User user = entityManager.find(User.class, "jhon@domain.com");
...

Após a invocação, os logs do hibernate mostram:

select user1_.email as email2_0_, person2_.id as id1_1_, person2_.email as email1_1_
from users user1_ left outer join people person2_ on user1_.email=person2_.id
where user1_.email=?

Como você pode ver, a junção está errada porque está comparando users.email com people.id (usuário1_.email=pessoa2_.id), então ele retorna um Do utilizador sem o seu correspondente Pessoa.

Alguma idéia de como posso consertar isso?

Muito obrigado !!

Foi útil?

Solução

Acho que você deveria repensar seu modelo de dados.O relacionamento entre Usuário e Pessoa se parece mais com uma herança.

Para o problema com seus mapeamentos, veja aqui para mais discussões:

Provedores JPA:por que relacionamentos/FKs para colunas não-PK funcionam no Hibernate e no EclipseLink?

A especificação JPA permite referências a colunas de chave não primária?

Outras dicas

A rigor, a especificação JPA não permite referências a colunas de chave não primária.Pode funcionar em algumas implementações JPA, mas não é adequado.

No entanto, acho que você pode fazer isso tornando o relacionamento bidirecional e pertencente ao lado da chave não primária:

@Entity
public class Person {

    @Id
    private long id;

    @OneToOne
    @JoinColumn(name = "email")
    private User user;

    public String getEmail() {
        return user.getEmail();
    }

    public void setEmail(String email) {
        // left as an exercise for the reader
    }

}

@Entity
public class User {

    @Id
    private String email;

    @OneToOne(mappedBy = "user")
    private Person person;

}

Na verdade, eu ainda não tentei isso, então advertência hackor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top