Search code examples
javajpaopenjpa

JPA cross unidirectional OneToOne


I have two entity-classes A and B. For A there is only one instance of class B. Through a lifecicle of application I need to create new instnace of B for A. But for history log I need to store previous instance of B with links to an this A instance. So I created next mapping:

@Entity
class A {
    @OneToOne
    @JoinColumn(name="B_ID")
    B b;
}

@Entity
class B {
    @OneToOne
    @JoinColumn(name="A_ID")
    A a;
}
///////
CREATE TABLE A_TABLE (ID uuid, B_ID uuid, FOREIGN KEY (B_ID) REFERENCES B_TABLE(ID));
CREATE TABLE B_TABLE (ID uuid, A_ID uuid, FOREIGN KEY (A_ID) REFERENCES A_TABLE(ID));

I already have some correct data in my tables, but each time, when I trying to get any instance of A class, the b field is null. So, what am I doing wrong?

UPD_0 Ok, here what I'm realy dealing with:

@MappedSuperclass
public abstract class BaseUuidEntity {
     @Id
     @Column(name = "ID")
     @Persistent
     protected UUID id;
}

@MappedSuperclass
public class StandartEntity extends BaseUuidEntity { ... }
@MappedSuperclass
public abstract class AbstractEntity extends BaseUuidEntity { ... }
@Entity(name = "CardEntity")
@Table(name = "TBL_CARD")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "CARD_TYPE", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("0")
public class CardEntity extends AbstractEntity { ... }

@Entity("aEntity")
@DiscriminatorValue("1")
@Table(name = "A_TABLE")
class A extends CardEntity { 
    @OneToOne
    @JoinColumn(name="B_ID")
    B b;
    public String getBName() {
        return b.getName(); // NullPointerException
    }
}
@Entity("bEntity")
@Table(name = "B_TABLE")
class B extends StandartEntity {
    @Column(name="name")
    String name;
    public String getName() {
        return this.name;
    }
}

-- A_TABLE (ID, B_ID)
'41a2647d-2ef6-f507-92ee-bff0f784b6f3', '5d3c66da-b377-11e4-bc9c-1008b124eacf'
-- B_TABLE (ID, A_TABLE, NAME)
'5d3c66da-b377-11e4-bc9c-1008b124eacf', '41a2647d-2ef6-f507-92ee-bff0f784b6f3', 'Some text'

I'm getting all A entities (in my case - it's one)

select e from aEntity e

and trying to get name of b entity in each of them, but getting nullpointer, cause b is null;


Solution

  • I'm not sure if it will make any difference, but try changing the code in getBName() to use the getter instead of directly referencing the instance variable b:

    public String getBName() {
        return getB().getName();
    }
    

    instead of:

    public String getBName() {
        return b.getName(); // NullPointerException
    }
    

    I suspect that this could be the issue because JPA implementations create proxies for entities, which are usually subclasses of your entities, and these proxies override your getters and setters. So if you don't use the getter it could be that the instance variable does not get initialized properly.