Instance save transient before

Hi!

I guess you missed me :rofl:

Upgraded my Hibernate core from 6.5.2.Final to 6.6.0.Final and got this exception while trying to delete a record using repository method:

TransientObjectException
persistent instance references an unsaved transient instance of ‘com.thevegcat.app.entity.article.Article’ (save the transient instance before flushing)

The code of my app is the same and the only change is dependency upgrade previously mentioned.
When I look at the migration guide, there is no mention of transients.
Also I don’t understand the message because I expect transients not to be persisted if I had one, but the message asks me the opposite - to persist transients.
No matter my understaning or maybe better to say lack of understanding - I’m not sure is it a bug or a feature and the main question is should change my code to handle this new behaviour or not.

Thanks a lot!
Hrvoje

You’re probably being hit by a bugfix that took place in version 6.6.0 that involved transient-checks for deleted entities that are still referred to from associations of other entities in the persistence context.

You’re probably forgetting to null-out some association after deleting the target entity.

1 Like

I fixed it:

  • set Article property priceInfos (which is List<PriceInfo>) to null,
  • delete all PriceInfo(s) by Article ID from PriceInfo repository,
  • delete Article from Article repository.
@Override @Transactional(readOnly = false)
public void deleteById( final Integer id ) {
	final Article entity = getById( id );
	if (entity == null) {
		throw new VegArticleNotFoundException(
			ENTITY_NAME + " not found (ID = " + id + ").");
	}
	entity.setPhotos( null );
	this.photoService.deleteByIds(
		entity.getPhotos().stream().map( Photo::getId ).toList()
	);
	entity.setPriceInfos( null );
	this.priceInfoService.deleteByArticleId( id );
	this.articleRepository.delete( entity );
}

@Override
public void deleteByArticleId( final Integer articleId ) {
	final JPAQueryFactory jpaQueryFactory =
			new JPAQueryFactory( this.entityManager );
	final QPriceInfo priceInfo = QPriceInfo.priceInfo;
	jpaQueryFactory
		.delete( priceInfo )
		.where( priceInfo.article.id.eq( articleId ) )
		.execute();
}