OneToOne relationship for a non primary key column

RDV picture RDV · Nov 18, 2013 · Viewed 15.1k times · Source

I'm having a problem when I query an entity who has a OneToOne relationship with another one. This is the scenario:

Database tables:

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

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

Test data:

insert into users (email) values ('[email protected]');
insert into users (email) values ('[email protected]');

insert into people (id, email) values (1, '[email protected]');
insert into people (id, email) values (2, '[email protected]');

Entities:

@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;
    }
}

Invocation:

...
User user = entityManager.find(User.class, "[email protected]");
...

After de invocation, the hibernate's logs shows:

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=?

As you can see, the join is wrong because is comparing users.email with people.id (user1_.email=person2_.id), so it returns an User without its corresponding Person.

Any ideas about how can I fix it?

Thanks a lot !!

Answer

Alan Hay picture Alan Hay · Nov 18, 2013

I think you should rethink your datamodel. The relationship between User and Person looks more like one of Inheritance.

For the issue with your mappings as they stand see here for some further disussion:

JPA providers: why do relationships/FKs to non-PK columns work in Hibernate and EclipseLink?

Does the JPA specification allow references to non-primary key columns?