直接在JPA / JPQL中将行插入连接表?

时间:2014-06-19 02:37:59

标签: java jpa jpa-2.0 jpql spring-data-jpa

JPA中有没有办法直接将行插入连接表?我有以下合同和附件实体:

public class Contract implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Version
    @Column(name = "version")
    private Integer version;

    private String number;
    private String volume;

    @ManyToMany
    @JoinTable(joinColumns = @JoinColumn(name = "contract_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "attachment_id", referencedColumnName = "id"))
    private List<Attachment> attachments;
}

Attachment实体:

public class Attachment implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Version
    @Column(name = "version")
    private Integer version;

    private String name;
}

由于线程并发问题,我想直接向合同添加附件而无需加载合同,将附件添加到列表中并保留/保存合同,因为Contract对象中没有更新数据本身。为了更加冗长,我有多个并行保存附件的线程,如果我要在所有这些线程中保留Contract,我需要进行某种并发控制以避免OptimisticLockExceptions。鉴于Contract实体没有被修改(只有连接表是),我不想放入瓶颈,只是直接更新连接表。

JPA和/或JPQL中有没有办法直接在连接表中插入行?工作流程将保留附件,然后将相应的行插入连接表。

有没有办法从实体中检索JPA生成的连接表名称?

DDL:

CREATE TABLE `contract` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `number` varchar(255) DEFAULT NULL,
  `volume` varchar(255) DEFAULT NULL,
  `version` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;


CREATE TABLE `attachment` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `version` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=197 DEFAULT CHARSET=utf8;


CREATE TABLE `contract_attachment` (
  `contract_id` bigint(20) NOT NULL,
  `attachment_id` bigint(20) NOT NULL,
  UNIQUE KEY `UK_27094bpt88d7bfngq5v52jrs` (`attachment_id`),
  KEY `FK_i1ycj6ewd536bky08t0jjh15d` (`contract_id`),
  CONSTRAINT `FK_i1ycj6ewd536bky08t0jjh15d` FOREIGN KEY (`contract_id`) REFERENCES `contract` (`id`),
  CONSTRAINT `FK_27094bpt88d7bfngq5v52jrs` FOREIGN KEY (`attachment_id`) REFERENCES `attachment` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

1 个答案:

答案 0 :(得分:0)

看起来您需要将级联属性添加到@ManyToMany注释。使用PERSIST或ALL。
但是真的不清楚描述,你说你不想加载合同,但你怎么坚持/保存合同而不加载?

如果您真的不想加载合同并只保留附件,则需要将@ManyToMany关系添加到您的附件中。然后添加合同(您仍然需要加载它,但您不需要更新它)。它应该是这样的:

@ManyToMany
@JoinTable(joinColumns = @JoinColumn(name = "attachment_id", referencedColumnName = "id"), inverseJoinColumns =  @JoinColumn(name = "contract_id", referencedColumnName = "id"))
private List<Contract> contracts;