简体   繁体   中英

Hibernate: @OneToOne not producing “one to one” relationship in database

I'm relatively new to JPA and Hibernate and am trying to see how the @OneTo One annotation works, let's say I have an entity "Task" with the following relation:

 @OneToOne
    @JoinColumn(name = "manager_id")
    private Manager manager;

And there's the entity "Manager":

@Entity
@Table(name = "manager")
public class Manager {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;
 private String name;

 public Manager() {
 }

When I run the test file along with the "hibernate.hbm2ddl.auto" set to "update" I get a Many to One relation in the database (as you can see, there is no unique constraint of any kind that'd make it a one to one relation):

CREATE TABLE IF NOT EXISTS `timesheet`.`task` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `completed` BIT(1) NOT NULL,
  `description` VARCHAR(255) NULL DEFAULT NULL,
  `manager_id` BIGINT(20) NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  INDEX `FK3635851B178516` (`manager_id` ASC),
  CONSTRAINT `FK3635851B178516`
    FOREIGN KEY (`manager_id`)
    REFERENCES `timesheet`.`manager` (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

To be sure of this I tried adding two records with the same manager id and were indeed added, I also tried setting the unique constraint like " @Table(name = "Task",uniqueConstraints = @UniqueConstraint(columnNames =... " but no luck. So Why is this happening and what's exactly the pros of using @OneToOne annotaion if no application logic is applied to validate this?

Also, Is there any chance that Hibernate is not able to do the DDL generation properly? (I know that generation of schemas through hibernate is only meant for testing)

In a unidirectional relationship you will get the expected unique constraint if you mark it as "optional=false". You also get it if you set the join column explicitly as unique, of course.

So either

@OneToOne(optional=false)
    @JoinColumn(name = "manager_id")
    private Manager manager;

or

@OneToOne
    @JoinColumn(name = "manager_id", unique=true)
    private Manager manager;

So why do you need to mark it as not optional? My guess is that, when a value is optional, the column can contain many null values, but in many databases this can not be done when a unique constraint is present. You can do it in MySQL though, so maybe the Hibernate generator is not taking the database into account in this case (a bug?). See a discussion about MySQL handling of nulls here .

I had this issue too and I just needed to add the referenced column so I can get a generated table:

@Entity(name = "news")
 public class News extends BaseEntity {

    @Column(length = 500)
    private String title;
    @Column(length = 2000)
    private String description;

    @OneToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "file_id", referencedColumnName = "id", unique = true)
    private Picture picture;
}

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