1

I have searched and found similar issues, but they don't quite seem to be the same problem as

I have a few entities mapped like this:

Person
  |
  +--User

I want to add a new entity PersonPartDeux with a OneToOne mapping to Person. The resulting mapping should look something like this:

Person + PersonPartDeux
  |
  +--User

When I do so, a NullPointerException is thrown while trying to load the mapping:

java.lang.NullPointerException
    at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:135)

How do I specify the mapping so I can avoid this exception?

Here's my code:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Person implements Serializable
{
    @Id
    @GeneratedValue
    public Long id;

    @Version
    public int version = 0;

    public String name;

    @OneToOne(cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    public PersonPartDeux personPartDeux;
}

@Entity
public class PersonPartDeux implements Serializable
{
    @Id
    @GeneratedValue(generator = "person-primarykey")
    @GenericGenerator(
        name = "person-primarykey",
        strategy = "foreign",
        parameters = @Parameter(name = "property", value = "person")
    )
    public Long id = null;

    @Version
    public int version = 0;

    @OneToOne(optional=false, mappedBy="person")
    public Person person;

    public String someText;
}

@Entity
@PrimaryKeyJoinColumn(name = "person_Id")
public class User extends Person
{
    public String username;
    public String password;
}

As for why I'm bothering, I need both the inheritance and the OneToOne mapping to solve different known issues in my application.

Community
  • 1
  • 1
Merlyn Morgan-Graham
  • 58,163
  • 16
  • 128
  • 183

1 Answers1

0

Attach the Hibernate source to your project, so you can click thru or 'Open Type' (Ctrl-Shift-T in Eclipse) to view the OneToOneSecondPass source.

Seeing the source, will give you a clear indication as to what needs to be specified.

In my source (Hibernate 4.1.7), line 135 is

propertyHolder.addProperty( prop, inferredData.getDeclaringClass() );

However you're probably using an earlier version.

Looking at the mappings, I'm suspicious of the @OneToOne definition -- mappedBy="person".

@OneToOne(optional=false, mappedBy="person")
public Person person;

What does it usefully mean, to map an association property by itself? Hibernate already knows the property is a OneToOne -- you just told it that.

Pointing the underpinning mapping/ FK of the property, at itself.. probably isn't actually telling Hibernate any correct or useful information.

Here's an example from the HB dosc, perhaps showing better how to do what you want:

@Entity
class MedicalHistory implements Serializable {
  @Id Integer id;

  @MapsId @OneToOne
  @JoinColumn(name = "patient_id")
  Person patient;
}

@Entity
class Person {
  @Id @GeneratedValue Integer id;
}

Source: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/ (3.5 docs off JBoss site.)

Cheers, hope this helps.

Thomas W
  • 13,940
  • 4
  • 58
  • 76
  • http://stackoverflow.com/questions/787698/jpa-hibernate-one-to-one-relationship - I have a shared primary key which this answer claims doesn't work unless I do this mapping. – Merlyn Morgan-Graham Oct 02 '12 at 19:09
  • And yeah, I'm using the Hibernate version that comes with Seam 2.0.1.GA, which I can't really upgrade right now :) – Merlyn Morgan-Graham Oct 02 '12 at 19:10
  • 1
    You were right about that mapping. Changing `mappedBy="person"` to `mappedBy="personPartDeux"` solved it for my example. Unfortunately this isn't the problem in my *real* code, so I'm going to have to dig further for a real repro of my problem. I'll do that in another question, since you answered the one I've asked here. – Merlyn Morgan-Graham Oct 02 '12 at 19:37