在@ElementCollection上指定主键

时间:2015-05-05 12:56:30

标签: java hibernate jpa orm hibernate-mapping

因此,如果某些表缺少主键,那么innodb的行为可能会导致问题。

因此,对于Hibernate,我正在寻找一个键来指定@ElementCollection表上的主键,并将Set作为底层数据结构。

我找到了一种使用地图的主键的方法,但它有点奇怪,因为我不需要地图。

我还找到了与@Embeddable相关的答案,但我不需要那种复杂性。我在我的实体中使用Set或Set作为数据结构。

知道如何实现这个目标吗?

3 个答案:

答案 0 :(得分:14)

如果你使用Set并使元素Column不为null,那么hibernate将使用join列和element列创建一个主键。

示例:

@Column(name = "STRINGS", nullable = false)
@ElementCollection
private Set<String> strings;

答案 1 :(得分:2)

@ElementCollection无法使用主键,因为Embeddable类型无法使用标识符。

您可以add an @OrderColumn优化生成的SQL语句。

如果您需要主键,则应将@ElementCollection转换为@OneToMany关联。

答案 2 :(得分:0)

在 Spring Boot / Data JPA 2.5.2、hibernate-core 5.4.32 上测试:

@Entity
@Table(name = "user")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Data
@NoArgsConstructor
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

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

    @ElementCollection(fetch = FetchType.EAGER, targetClass = Role.class)
    @Enumerated(EnumType.STRING)
    @CollectionTable(
        name = "user_role",
        joinColumns = @JoinColumn(name = "user_id")
    )
    @Column(name = "role", nullable = false)
    private Set<Role> roles; // public enum Role {ADMIN,USER}
}

生成 MySQL 表:

CREATE TABLE `user_role` (
  `user_id` bigint(20) NOT NULL,
  `role` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`user_id`,`role`),
  CONSTRAINT `FK_random_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
)