PropertyAccessException when serializing bean with lazily loaded (bytecode instrumentation) one-to-one relationship

StackOverflow https://stackoverflow.com/questions/22746734

Question

I work on a WildFly web project with JPA/Hibernate. During my time developing this software, I've come to hate Hibernate with a burning passion, as many others apparently did. I wish I didn't use it in the first place, but the project is too far along to change the approach now. I worked around many of it's silly quirks and "feature-not-a-bug"s, but now I have just one more left and it's driving me crazy.

I have a bean called GenericPerson, which can have many "roles" (like Customer, User etc). Each role is in its own database table, and associated with parent person via primary key (id). Of course, I don't want to load roles unless I really need them, so I went on and used Hibernate's lazy loading feature. It appears that for @OnoToOne relationships, bytecode instrumentation has to be used. So I implemented it via Maven, and it works. Here is the code sample.

@Entity
@Table(schema="public", name="generic_person")
public class GenericPerson extends BaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    ...

    // Bidirectional one-to-one association to User
    @OneToOne(optional=true, fetch=FetchType.LAZY)
    @LazyToOne(value=LazyToOneOption.NO_PROXY)
    @PrimaryKeyJoinColumn
    @JsonView(JacksonViews.EagerLoad.class)
    @JsonManagedReference("user")
    private User user;

    ...
}

@Entity
@Table(name="user")
public class User extends BaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    ...

    @OneToOne(mappedBy="user", optional=false)
    @JsonBackReference("user")
    private GenericPerson genericPerson;

    ...
}

Now, everything is fine if I don't need the information about the user (and therefore never lazy-initialize "user" field). It is also fine if I want to use eager loading and the user for this GenericPerson exists. However, if the associated user does not exist, when RestEasy serializes the bean via Jackson, I get the exception:

org.hibernate.PropertyAccessException:
could not get a field value by reflection getter of User.id

Well, of course you can't, dear Hibernate, the user does not exist! This does not happen when class is not enhanced (so no lazy loading). I tried switching mappedBy attribute and @PrimaryKeyJoinColumn annotation from one side to the other, but it did not help. Does anyone have an idea how to solve this issue? Alternative design ideas (to using @OneToOne) are also welcome.

Was it helpful?

Solution

Funny thing. For a completely unrelated reason, I decided to move all annotations from fields to getter methods. Once I did that, this problem disappeared. I hope this helps someone in similar situation.

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