1

I have been trying to map some "OneToOne" relationships between two users via an intermediate class called Guardian. When i try to retrieve a user (and his guardians) i get an internal server error in return from Glassfish (Open edition v4.0). There is however no stack trace of any kind or any error displayed in the logs. I suspect that the issue is my mapping within the JPA classes.

Starting the server i get two warnings related to the Guardian class which I don't really understand:

WARNING: The reference column name [GUARDIAN] mapped on the element [method getGuardianUserBean] does not correspond to a valid id or basic field/column on the mapping reference. Will use referenced column name as provided.

WARNING: The reference column name [OWNER] mapped on the element [method getOwnerUserBean] does not correspond to a valid id or basic field/column on the mapping reference. Will use referenced column name as provided.

SQL create statements:

create table HOMEFREE."user" (
    userid integer GENERATED ALWAYS AS IDENTITY,
    name varchar(255) not null,
    displayname varchar(255) unique not null,
    password varchar(255) not null,
    tlf integer,
    facebookID varchar(255),
    googleid varchar(255),
    authtoken varchar(255),
    email varchar(255) unique not null,
    primary key(userid)
);

create table HOMEFREE."guardian" (
    guardianId integer GENERATED ALWAYS AS IDENTITY,
    owner integer not null,
    guardian integer not null,
    confirmed boolean not null,
    primary key(guardianId),
    foreign key(owner) references homeFree."user"(userid),
    foreign key(guardian) references homeFree."user"(userid)
);

Relevant fields/annotations in entity classes:

@Entity
@Table(name = "\"user\"", schema = "HOMEFREE")
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int userId;

    @OneToMany(mappedBy = "ownerUserBean", fetch = FetchType.EAGER)
    private List<Guardian> guardians;
}

@Entity
@Table(name="\"guardian\"", schema="HOMEFREE")
public class Guardian implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int guardianId;

    @OneToOne
    @PrimaryKeyJoinColumn(name="OWNER", referencedColumnName="USERID")
    private User ownerUserBean;

    @OneToOne
    @PrimaryKeyJoinColumn(name="GUARDIAN", referencedColumnName="USERID")
    private User guardianUserBean;

    private boolean confirmed;  
}
Anders
  • 125
  • 1
  • 3
  • 13

1 Answers1

0

Try using @JoinColumn instead of @PrimaryKeyJoinColumn.

@OneToOne
@JoinColumn(name="OWNER", referencedColumnName="USERID")
private User ownerUserBean;

@OneToOne
@JoinColumn(name="GUARDIAN", referencedColumnName="USERID")
private User guardianUserBean;

According to spec the latter should be used to join the primary table of an entity subclass in the JOINED mapping strategy to the primary table of its superclass (exact definition available here)

Blekit
  • 663
  • 4
  • 7
  • This removed the initial warning. The server still throws a HTTP status of 500. Still no sign of the error in the log file. – Anders Apr 02 '14 at 12:10
  • Well, then I suppose you have some other problem with either your application or server itself. Are you able to access some part of your application or it doesn't even deploy successfully? – Blekit Apr 02 '14 at 12:30
  • I think I found the problem. Only Users with guardians cause the server to crash. This causes an infinite recursion since the list of guardians is persisted within the owner value of the Guardian object itself. I need to find a way to persist the User in Guardian without persisting the guardian list. – Anders Apr 02 '14 at 14:20