I have this class with UUID as primary key:
@Entity
@Table(name = "JOURNAL")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class JournalEntity extends AbstractEntity<UUID> {
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID",
strategy = "it.frogo.journal.dao.model.UUIDGenerator")
@Column(name = "id", updatable = false, nullable = false)
UUID id;
String name;
@Override
public UUID getId() {
return id;
}
}
I want to be able to persist a new entity with his own id if it's not null or generate a random one otherwise.
I've found this question:
How to generate ID only if it's null on persisting
so i created a custom IdentifierGenerator like this:
public class UUIDGenerator implements IdentifierGenerator {
@Override
public Serializable generate(SharedSessionContractImplementor session, Object arg) throws HibernateException {
log.info("UUID generation");
try {
final Method m = arg.getClass().getMethod("getId");
if (!m.getReturnType().equals(UUID.class)) {
throw new NoSuchMethodException();
}
final UUID invoke = (UUID)m.invoke(arg);
return invoke == null ? UUID.randomUUID() : invoke;
} catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new HibernateException("invalid entity");
}
}
}
What happens is that if i try to save an instance through the following repository
@Repository
public interface JournalRepository extends JpaRepository<JournalEntity, UUID>, JpaSpecificationExecutor<JournalEntity> {
}
is that the custom generator is called only if id is null on the entity.
When i set a pre-generated uuid on the entity the custom generator is not called and an exception is thrown:
org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: it.frogo.journal.dao.model.JournalEntity; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: it.frogo.journal.dao.model.JournalEntity
Using directly the entityManager i should probably be able to merge it without issues, but imho that defeats the purpose of having a repository in the first place.
So, am i missing something? There is really no other way to make this work with JpaRepository only?
Thank you.