hibernate IdGeneration

hibernate IdGeneration

https://www.baeldung.com/hibernate-identifiers

Simple Identifier

using @Id to a single property of one of these types: Java primitive and primitive wrapper types, String, Date, BigDecimal, BigInteger.

Generated Identifier

Auto

the persistence provider will determine values based on the type of the primary key attribute. This type can be numerical or UUID.

For numeric values, the generation is based on a sequence or table generator,

For UUID values will use the UUIDGenerator.

Identity

expects values generated by an identity column in the database, meaning they are auto-incremented.


@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
private long studentId;

SEQUENCE

This generator uses sequences if they're supported by our database, and switches to table generation if they aren't.

@Entity
public class User {
@Id
@GeneratedValue(generator = "sequence-generator")
@GenericGenerator(
name = "sequence-generator",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
@Parameter(name = "sequence_name", value = "user_sequence"),
@Parameter(name = "initial_value", value = "4"),
@Parameter(name = "increment_size", value = "1")
}
)
private long userId;

// ...
}

SEQUENCE is the generation type recommended by the Hibernate documentation.

Composite Identifiers

Finally, if we're going to access parts of the composite key individually, we can make use of @IdClass, but in places where we frequently use the complete identifier as an object, *@EmbeddedId* is preferred.

The primary key class must fulfill several conditions:

  • it should be defined using @EmbeddedId or @IdClass annotations
  • it should be public, serializable and have a public no-arg constructor
  • it should implement equals() and hashCode() methods

embeded


@Embeddable
public class OrderEntryPK implements Serializable {

private long orderId;
private long productId;

// standard constructor, getters, setters
// equals() and hashCode()
}

@Entity
public class OrderEntry {

@EmbeddedId
private OrderEntryPK entryId;

// ...
}

@Test
public void whenSaveCompositeIdEntity_thenOk() {
OrderEntryPK entryPK = new OrderEntryPK();
entryPK.setOrderId(1L);
entryPK.setProductId(30L);

OrderEntry entry = new OrderEntry();
entry.setEntryId(entryPK);
session.save(entry);

assertThat(entry.getEntryId().getOrderId()).isEqualTo(1L);
}

IdClass

The @IdClass annotation is similar to the @EmbeddedId, except the attributes are defined in the main entity class using @Id for each one.

@Embeddable
public class OrderEntryPK implements Serializable {

private long orderId;
private long productId;

// standard constructor, getters, setters
// equals() and hashCode()
}

@Entity
@IdClass(OrderEntryPK.class)
public class OrderEntry {
@Id
private long orderId;
@Id
private long productId;

// ...
}
@Test
public void whenSaveIdClassEntity_thenOk() {
OrderEntry entry = new OrderEntry();
entry.setOrderId(1L);
entry.setProductId(30L);
session.save(entry);

assertThat(entry.getOrderId()).isEqualTo(1L);
}

others

TableGenerator uses an underlying database table that holds segments of identifier generation values.

we can define our custom generator by implementing the *IdentifierGenerator* interface.

eg

ublic 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");
}
}

https://stackoverflow.com/questions/10041938/how-to-choose-the-id-generation-strategy-when-using-jpa-and-hibernate