Reputation: 561
I am new to spring and spring boot and playing around by developing a simple application. I have the following usecase as mentioned below.
I have the following class definition in my spring boot project.
public class Issue {
@Id
@GenericGenerator(name = "sequence_issue_id", strategy = "com.app.mycompany.AgileCenterServices.util.IssueIdGenerator",
parameters = @Parameter(name = "ProjectKey", value = "PeopleCenter" ))
@GeneratedValue(generator = "sequence_issue_id")
@Column(unique = true)
private String id;
private String projectId;
}
I have a IssueIdGenerator class that sets dynamic value to the id parameter in the Issue POJO class.
However, while doing so, I would like to set a prefix to the id parameter.
How should I be sending this dynamic prefix value to the IssueIdGenerator class.
The prefix value is not a fixed value and will be received as an attribute to the Issue POJO class.
Hence I would like to pass this prefix value which is present as an attribute in the Issue POJO class to the IssueIdGenerator class.
Upvotes: 0
Views: 1855
Reputation: 337
The closer you will get (Using a Generator) to your usecase is by defining a Custom Generator.
An example available in https://www.baeldung.com/hibernate-identifiers is:
Let’s create a generator that builds identifiers containing a String prefix and a number:
public class MyGenerator implements
IdentifierGenerator, Configurable {
private String prefix;
@Override
public Serializable generate(
SharedSessionContractImplementor session, Object obj)
throws HibernateException {
String query = String.format("select %s from %s",
session.getEntityPersister(obj.getClass().getName(), obj)
.getIdentifierPropertyName(),
obj.getClass().getSimpleName());
Stream ids = session.createQuery(query).stream();
Long max = ids.map(o -> o.replace(prefix + "-", ""))
.mapToLong(Long::parseLong)
.max()
.orElse(0L);
return prefix + "-" + (max + 1);
}
@Override
public void configure(Type type, Properties properties,
ServiceRegistry serviceRegistry) throws MappingException {
prefix = properties.getProperty("prefix");
}
}
>
In this example, we override the generate() method from the IdentifierGenerator interface and first find the highest number from the existing primary keys of the form prefix-XX.
Then we add 1 to the maximum number found and append the prefix property to obtain the newly generated id value.
Our class also implements the Configurable interface, so that we can set the prefix property value in the configure() method.
Next, let’s add this custom generator to an entity. For this, we can use the @GenericGenerator annotation with a strategy parameter that contains the full class name of our generator class:
@Entity
public class Product {
@Id
@GeneratedValue(generator = "prod-generator")
@GenericGenerator(name = "prod-generator",
parameters = @Parameter(name = "prefix", value = "prod"),
strategy = "com.baeldung.hibernate.pojo.generator.MyGenerator")
private String prodId;
// ...
}
Also, notice we’ve set the prefix parameter to “prod”.
Let’s see a quick JUnit test for a clearer understanding of the id values generated:
@Test
public void whenSaveCustomGeneratedId_thenOk()
{
Product product = new Product();
session.save(product);
Product product2 = new Product();
session.save(product2);
assertThat(product2.getProdId()).isEqualTo("prod-2");
}
Here, the first value generated using the “prod” prefix was “prod-1”, followed by “prod-2”.
Another alternative would be to use a Composite Key (JPA specification):
A composite primary key must correspond to either a single persistent field or property or to a set of such fields or properties as described below. A primary key class must be defined to represent a composite primary key. Composite primary keys typically arise when mapping from legacy databases when the database key is comprised of several columns. The EmbeddedId and and IdClass annotations are used to denote composite primary keys. See sections 9.1.14 and 9.1.15.
Upvotes: 1