简体   繁体   中英

JPA/Hibernate - shared primary key

I wanted to create bidirectional one to one relationship with shared primary key.

As it is stated here JPA Hibernate One-to-One relationship I have:

@Entity
public class UserProfileInformation {

    @Id
    @GeneratedValue(generator = "customForeignGenerator")
    @org.hibernate.annotations.GenericGenerator(
        name = "customForeignGenerator",
        strategy = "foreign",
        parameters = @Parameter(name = "property", value = "userEntity")
    )
    long id;

    private long itemsPerPage;

    @OneToOne(mappedBy="userProfileInformation")
    private UserEntity userEntity;
...}

@Entity
@Table(name = "UserTable")
public class UserEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String publicName;

    private String password;

    private String emailAddress;

    private String name; 

    private boolean active;

    @OneToOne(cascade=CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private UserProfileInformation userProfileInformation;
...}

now, when I try to persist my user in the database, I am getting org.hibernate.id.IdentifierGenerationException: null id generated for:class pl.meble.taboret.model.UserProfileInformation . Is it because, when userProfileInformation is persisted to the database userEntity doesn't have id generated at that point?

Also, what can I do to create bidirectional relationship with shared primary key in my example?

EDIT: Requested code, this is simple controller to test the operation of persisting UserEntity.

@Controller
@RequestMapping("/test")
public class TestController {
    @Autowired
    UserDao userDao;

    @RequestMapping(method= RequestMethod.GET)
    public String t(Model model){
        UserEntity entity=new UserEntity();
        entity.setActive(false);
        entity.setEmailAddress("a");
        entity.setName("name");
        entity.setPassword("qqq");
        entity.setPublicName("p");
        UserProfileInformation p = new UserProfileInformation(entity);
        entity.setUserProfileInformation(p);
        userDao.addUser(entity);
        return "login";
    }
}

I think the problem is with the id generation strategy. For hibernate @GeneratedValue(strategy = GenerationType.AUTO) translates into a native identifier generation. This means that hibernate expects an identity id field for the UserTable.

I don't know exactly how SQLite works in terms of identity columns, but it seems from this SO question is a little different (see the second answer).

Anyway if you plan to run your application on multiple databases is better for portability to change the id generation strategy from GenerationType.AUTO and use hibernate enhanced generators: SequenceStyleGenerator or TableGenerator . See this link in the hibernate documentation.

EDIT:

I tried to reproduce your problem, and it seems that SQLite dialect is not among the officially supported hibernate dialects . Meanwhile I tested your case with the H2 embeded database and it works as expected: your mappings are correct.

If you are using an unofficial SQLite dialect it might be a bug with this dialect.

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