Created
May 21, 2021 12:16
-
-
Save CarlosPanarello/8f3a94026328410da40a9c3f0e2f749f to your computer and use it in GitHub Desktop.
Gerador de sequencia
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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