避免使用MapsId在复合键中生成ID

时间:2019-06-18 23:44:28

标签: hibernate hibernate-mapping

我正在尝试创建具有附加列的联接表实体。 如果联接表实体持久化过程中子实体之一先前未持久化,如何避免生成复合ID?我正在使用@MapsId从实体获取组合键的部分ID。

当我尝试使用其中未指定的未持久存储库(未生成RepositoryId)保存AssetRepositoryEntity时,我会以其他方式期望出现异常或失败。但是,Hibernate尝试为未持久存储库生成ID

这是父实体:

@Entity
@Table(name = "ASSET_REPO_MAP")
public class AssetRepoMapEntity implements Serializable {

    @EmbeddedId
    private AssetRepositoryId primaryKey;

    @ManyToOne(cascade = CascadeType.REMOVE)
    @MapsId("repositoryId")
    private RepositoryEntity repositoryEntity;

    @ManyToOne
    @MapsId("assetId")
    private AssetEntity assetEntity;

    @Column(name = "STATUS", nullable = false)
    private Status status = Status.NEW;

    public AssetRepoMapEntity(){}

    public AssetRepoMapEntity(RepositoryEntity repositoryEntity, AssetEntity assetEntity){
        this.repositoryEntity = repositoryEntity;
        this.assetEntity = assetEntity;
        this.primaryKey = new AssetRepositoryId(repositoryEntity.getId(),assetEntity.getAssetId());
    }
................................................................
................................................................

它具有复合密钥AssetRepository:

@Embeddable
public class AssetRepositoryId implements Serializable{

    @Column(name="repository_id")
    private String repositoryId;

    @Column(name="asset_id")
    private String assetId;

    private AssetRepositoryId(){
    }

    public AssetRepositoryId(String repositoryId, String assetId){
        this.repositoryId = repositoryId;
        this.assetId = assetId;
    }
..................................................................
..................................................................

和子实体RepositoryEntity:

@Entity(name = "repositoryEntity-v2")
@Table(name = "REPOSITORIES")
@DynamicInsert
@DynamicUpdate
public class RepositoryEntity implements Serializable {

    private static final long serialVersionUID = 3440851562367009351L;

    @Id
    @Column(name = "REPOSITORY_ID", nullable = false)
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String repository_id;

    @Column(name = "description", length = 512, nullable = false)
    private String description;
.....................................................................
.....................................................................
    @Column(name = "status", length = 64)
    @Enumerated(EnumType.STRING)
    private Status status = Status.ACTIVE;

    @OneToMany(mappedBy = "repositoryEntity", orphanRemoval = true)
    private Set<AssetRepoMapEntity> assetRepositoryList = new HashSet<AssetRepoMapEntity>();
....................................................................
....................................................................
据我了解,

@MapsId为AssetRepositoryId.repositoryId提供RepositoryEntity.repository_id。 还值得一提的是,我正在使用JpaRepository来保持 AssetRepoMapEntity:

@Repository(value = "assetRepoMapRepository-v2")
public interface AssetRepoMapRepository extends JpaRepository<AssetRepoMapEntity, AssetRepositoryId> {
}

我正在尝试保留AssetRepoMapEntity:

@RunWith(SpringRunner.class)
@TestConfiguration
public class AssetRepoMapTest {

    @Autowired
    private AssetRepository assetRepository;

    @Autowired
    private RepoRepository repoRepository;

    @Autowired
    private AssetRepoMapRepository assetRepoMapRepository;

    RepositoryEntity repositoryEntity;

    AssetEntity assetEntity;

    @Before
    public void setUp() {

        repositoryEntity = new RepositoryEntity();
        repositoryEntity.setName("repository1");
        repositoryEntity.setDescription("repository1 description");
        repositoryEntity.setPath("/repository1/path");
        repositoryEntity.setStatus(RepositoryEntity.Status.ACTIVE);

        assetEntity = new AssetEntity();
        assetEntity.setKey("....");
        assetEntity.setType(.....);
    }

    @Test
    public void insertAssetItemWithNotExistingRepository() {
        assetRepository.save(assetEntity1);
        AssetRepoMapEntity assetJoinRepositoryEntity = new AssetRepoMapEntity(this.repositoryEntity1,assetEntity1);


        assetRepoMapRepository.save(assetJoinRepositoryEntity);

        Optional<AssetRepoMapEntity> result = assetRepoMapRepository.findById(assetJoinRepositoryEntity.getPrimaryKey());
    }

}

预期结果:

异常,因为RepositoryEntity已创建但未持久保存(处于过渡状态),并且它的repository_id应该为空

实际结果: Hibernate尝试将下一条记录插入数据库中,以使“ AssetRepoMapEntity”的持久化合法化:

FE=> Parse(stmt=null,query="insert into repositories (status, repository_id) values ($1, $2)",oids={1043,1043})

o.postgresql.core.v3.QueryExecutorImpl   :  FE=> Bind(stmt=null,portal=null,$1=<'ACTIVE'>,type=VARCHAR,$2=<'3e3e31a2-9ba1-4863-843a-7b07ba30cf2b'>,type=VARCHAR)

1)它放弃了先前创建的实体,并且所有字段都已满足

2)生成新实体,仅生成repository_id属性字段(所有其他属性为空)

3)尝试插入生成的原始文件,但由于行之一不应该为null,因此以异常结束。在这种情况下,说明不能为空。

0 个答案:

没有答案