Question

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 ('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');

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, "jhon@domain.com");
...

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 !!

Was it helpful?

Solution

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?

OTHER TIPS

Strictly speaking, the JPA specification does not allow references to non-primary key columns. It may work in some JPA implementations, but it's not proper.

However, i think you can do this by making the relationship bidirectional, and owned by the side with the non-primary key:

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

}

I haven't actually tried that, though, so caveat hackor.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top