Second generator using sequence when you have UUID

I have an entity with the id of type uuid and for that I use construct

@Id
@GeneratedValue(strategy = GenerationType.UUID)
public UUID id;

I want to have another field (name code) of type String, values of which should also be generated at insert time by using database sequence, for instance PRJ001, PRJ002. I don’t have a problem with gaps that might occur, just want this field to be unique.

I created class EntityCodeGenerator which implements IdentifierGenerator and implemented the logic in generate method. Then I want to use it in my Entity as follows

@GenericGenerator(name = "projectCodeGenerator", type = EntityCodeGenerator.class,
            parameters = {
                @Parameter(name = "sequence", value = "seq_project_code"),
                @Parameter(name = "length", value = "3"),
                @Parameter(name = "prefix", value = "PRJ")
            })
@GeneratedValue(generator = "projectCodeGenerator")
public String code;

When I try to persist this entity code is null. What am I doing wrong and how I can achieve this goal?

You can only have a single @GeneratedValue per entity, which must be the identifier. What you are looking for is rather a ValueGenerator. See Hibernate ORM 5.6.15.Final User Guide

I’m on Hibernate 6.2
Tried to use this approach and it kinda works.
https://docs.jboss.org/hibernate/orm/6.2/javadocs/org/hibernate/annotations/ValueGenerationType.html
Few moments:

  1. In order to get the sequence value, I had to use JDBC, because with JPA it went into endless loop and eventually stackoverflow happened.
  2. If I persist the entity, the code is generated properly, but if after persist, I want to update other fields of the entity, the code is not set in the database, had to use flush right after persist to solve this problem.
  1. In order to get the sequence value, I had to use JDBC, because with JPA it went into endless loop and eventually stackoverflow happened.

You can also implement OnExecutionGenerator and use implement getReferencedColumnValues to provide the SQL fragment directly.

  1. If I persist the entity, the code is generated properly, but if after persist, I want to update other fields of the entity, the code is not set in the database, had to use flush right after persist to solve this problem.

No idea what you’re exactly doing in your code, but this shouldn’t be necessary.

I looked at the code https://github.com/hibernate/hibernate-orm/blob/6.3/hibernate-core/src/main/java/org/hibernate/generator/internal/SourceGeneration.java
and applied the same principle in my Generator.

As for the value not being generated in the scenario when I do persist and in the same session continue updating merged entity fields. I guess the issue was that I had INSERT_ONLY generation mode and apparently because I continue updating entity field values, the operation is “treated” as UPDATE. I changed getEventTypes to return INSERT_OR_UPDATE and adjusted the generate method to only generate if currentValue is null, otherwise return the currentValue. Everything works fine.