简体   繁体   中英

JPA OneToOne relationship

I am building a project using the Play framework and I am having trouble getting my head around JPA @OneToOne relationships .

I currently have two classes:


User Object

@Entity
@Table( name="users" )
public class Users extends Model {

    @OneToOne( mappedBy="userId", fetch=FetchType.LAZY, cascade = CascadeType.ALL )
    @ForeignKey( name="userId", inverseName="userId" )
    UserSettings userSettings;
    public userId;
    public userName;
}


UserSettings

@Entity
@Table( name="user_settings" )
public class UserSettings extends Model {

    @OneToOne( cascade = CascadeType.ALL,targetEntity=User.class )
    public String userId;
    public String xml;

    public UserSettings( String userId ){
        this.userId = userId;
    }
}


The idea is that I am trying to set the userId field within User as a foreign key within UserSettings . I have tried a few different ways to achieve this and my code always throws an error. The most common error I recveive is: Referenced property not a (One|Many)ToOne .

However, When I try to set the userId in UserSettings using the code above, I receive the following exception:

A javax.persistence.PersistenceException has been caught, org.hibernate.PropertyAccessException: could not get a field value by reflection getter of reader.User.id

Can anybody help explain how I can achieve my desired goal?

Read section 5.2 of the hibernate reference about the difference between entities and values. You're trying to map a String as an entity. Only entities can be a (One|Many)ToOne, as the error is telling you. Ie, instead of String userId , you should be using User user , and instead of mappedBy="userId" , mappedBy="user" .

If you extend Model, Play will generate an primary key "id" by default for each entity. If this is not what you want you should extend Generic model instead.

The simplest way would be to have user as a property of user settings:


@Entity
@Table( name="user_settings" )
public class UserSettings extends Model{
    @OneToOne
    public Users user;
...

@Entity
@Table( name="users" )
public class Users extends Model {
    @OneToOne(cascade = CascadeType.ALL)
    public UserSettings settings;

Maintaining User and UserSettings in each entity with OneToOne allows you to have bi-directional searches.
If you want to use your own key change from Model to GenericModel and defined your foreign key on the user object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM