我正在尝试创建具有附加列的联接表实体。 如果联接表实体持久化过程中子实体之一先前未持久化,如何避免生成复合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,因此以异常结束。在这种情况下,说明不能为空。