Skip to content

Instantly share code, notes, and snippets.

@CarlosPanarello
Created May 21, 2021 12:16
Show Gist options
  • Save CarlosPanarello/8f3a94026328410da40a9c3f0e2f749f to your computer and use it in GitHub Desktop.
Save CarlosPanarello/8f3a94026328410da40a9c3f0e2f749f to your computer and use it in GitHub Desktop.
Gerador de sequencia
package br.com.cep.model.banco.sequence;
import io.smallrye.mutiny.tuples.Tuple3;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Collectors;
import javax.print.DocFlavor.STRING;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.Configurable;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.internal.SessionImpl;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
/**
* Classe para criar uma sequencia com base nos outros atributos chaves da classe aonde
* ele esta sendo utilizado, para campos de data informar o formatado da data quando for diferente
* de YYY-MM-DD
* Exemplo de uso
* @Id
* @Column(name = "SEQ_USER")
* @GeneratedValue(generator = "generator-sequencial")
* @GenericGenerator(name = "generator-sequencial",
* parameters = @Parameter(name = "dateFormat", value = "DD-MM-YYYY"),
* strategy = "br.com.cep.model.banco.sequence.ChaveCompostaSequence")
* private Long sequencial;
*/
public class ChaveCompostaSequence implements IdentifierGenerator, Configurable {
private static final String DEFAULT_DATE_FORMAT = "YYYY-MM-DD";
private static final String TO_DATE = " TO_DATE('%s','%s') ";
private static final String STRING_VALUE = "'%s'";
private String dateFormat = DEFAULT_DATE_FORMAT;
@Override
public void configure(Type type, Properties properties,
ServiceRegistry serviceRegistry) throws MappingException {
if(properties.getProperty("dateFormat") != null){
dateFormat = properties.getProperty("dateFormat");
}
}
private String returnNamePropertyFromEntity(SharedSessionContractImplementor session, String name,
Object obj, Type type) {
if (type.isEntityType()) {
return name + "." + ((SessionImpl) session)
.getEntityPersister(obj.getClass().getCanonicalName(), obj)
.getIdentifierPropertyName();
}
return name;
}
private Object returnStringFromObjectValue(SharedSessionContractImplementor session, Object obj,
Type type) {
if (type.isEntityType()) {
return ((SessionImpl) session).getEntityPersister(obj.getClass().getCanonicalName(), obj)
.getIdentifier(obj, session);
}
if (type.getReturnedClass().equals(String.class)) {
return String.format(STRING_VALUE, obj);
}
if(type.getReturnedClass().equals(ZonedDateTime.class) ||
type.getReturnedClass().equals(Calendar.class) ||
type.getReturnedClass().equals(Date.class) ||
type.getReturnedClass().equals(LocalDate.class) ||
type.getReturnedClass().equals(LocalDateTime.class)){
return String.format(TO_DATE, obj, dateFormat );
}
if (type.getReturnedClass().equals(Long.class)) {
return String.valueOf(obj);
}
return obj;
}
@Override
public Serializable generate(SharedSessionContractImplementor session,
Object obj) throws HibernateException {
var entityName = obj.getClass().getSimpleName();
var entityPersist = ((SessionImpl) session)
.getEntityPersister(obj.getClass().getCanonicalName(), obj);
var pkField = Arrays.stream(obj.getClass().getDeclaredFields())
.filter(field -> field.getAnnotation(GenericGenerator.class) != null)
.findFirst().map(Field::getName).orElseThrow();
var querySelect = String.format("select max(%s) from %s", pkField, entityName);
var whereClause = Arrays
.stream(entityPersist.getIdentifier(obj, session).getClass().getDeclaredFields())
.map(Field::getName)
.map(i -> Tuple3
.of(i, entityPersist.getPropertyValue(obj, i), entityPersist.getPropertyType(i)))
.filter(t3 -> !t3.getItem1().equals(pkField))
.map(t3 -> String.format("%s = %s",
returnNamePropertyFromEntity(session, t3.getItem1(), t3.getItem2(), t3.getItem3()),
returnStringFromObjectValue(session, t3.getItem2(), t3.getItem3())))
.collect(Collectors.joining(" and "));
var query = Optional.of(whereClause)
.map(where -> querySelect + " where " + where)
.orElse(querySelect);
var ids = session.createQuery(query, Long.class).stream();
var max = ids.filter(Objects::nonNull)
.mapToLong(o -> Long.parseLong(o.toString()))
.max()
.orElse(0L);
return (max + 1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment