Issue
is there a way to perform insertion of an @Id
-column value into a non @Id
column when entity is being created/updated to avoid double-save
-ing?
@Entity
class DummyEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "dummy_id_generator")
@SequenceGenerator(name = "dummy_id_generator", sequenceName = "dummy_id_seq")
Long id;
Long rootId;
}
@Repository
class DummyEntityRepo implements JpaRepository<DummyEntity, Long> {}
@Service
class DummyEntityService {
@Autowired
DummyEntityRepo repo;
void save(DummyEntityVO newDummyEntity) {
var newEntity = newDummyEntity.mapToEntity();
// !!! double save here !!!
repo.save(newEntity);
if(newEntity.getRootId() == null) {
newEntity.setRootId(newEntity.getId());
repo.save(newEntity);
}
}
}
What I was thinking was, since @Id
is based on a sequence, I can try extracting next value from it and setting it as id
and rootId
before saving
Long nextId = // get next id somehow
newEntity.setId(newId);
if (newEntity.getRootId()) {
newEntity.setRootId(nextId);
}
repo.save(newEntity);
However:
- I don't like perspective of interfering with Hibernate's id acquisition & saving methods
- I found package
org.springframework.jdbc.support.incrementer
but unfortunately there is no sequence based OOB incrementer for my DB so it would require a custom implementation (found something promising here though)
Solution
@GeneratorType allows to generate/set values into entity during insertion phase. Suppose your entity looks like this:
@Entity
class DummyEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "dummy_id_generator")
@SequenceGenerator(name = "dummy_id_generator", sequenceName = "dummy_id_seq")
Long id;
@GeneratorType(type = RecordIdGenerator.class, when = GenerationTime.INSERT)
Long rootId;
}
And your RecordIdGenerator class looks like:
public class RecordIdGenerator implements ValueGenerator<Long> {
@Override
public Long generateValue(Session session, Object owner) {
return ((DummyEntity)owner).getId();
}
}
Then when you'll insert new record hibernate will generate similar queries:
Hibernate: select nextval ('dummy_id_seq')
Hibernate: insert into dummy (record_id, id) values (?, ?)
and record_id will be equal to id
Answered By - eparvan