Home > Blockchain >  How to add dynamic Prefix to ID Field Gerator for JPARepository at RUNTIME instead of this static So
How to add dynamic Prefix to ID Field Gerator for JPARepository at RUNTIME instead of this static So

Time:09-17

I used Static Prefix value as DEPT I can't change it depends on my dept attribute's value but I want to Add prefix to it dynamically based on the value to dept during the id generation. @GenericGenerator(name = "prod-generator", parameters = @Parameter(name = "prefix", value = "DEPT"), strategy = "com.otomate.registerservice.service.IdGenerator")

My UserModel Class

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
import lombok.Data;
import lombok.Getter;

@Data
@Entity
@Table(name = "user")
public class UserModel {
    @Id
    @GeneratedValue(generator = "prod-generator")
    @GenericGenerator(name = "prod-generator", parameters = @Parameter(name = "prefix", value = "DEPT"), strategy = "com.otomate.registerservice.service.IdGenerator")
    private String id;
    private String firstName;
    private String lastName;
    private String dept;
    @Column(unique = true)
    private String email;
    @Column(unique = true)
    private String phone;
    private String password;
    private String roles;
    private String skills;

}

IDGenerator Class

public class IdGenerator 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<String> 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");
    }

}

my input:

{ 
"firstName":"Dhamodaran",
"lastName":"N",
"dept":"SALES",
"password":"12345678",
"email":"[email protected]",
"phone":"1379143242",
"roles":"USER"

}

It's "dept": "SALES" so I want my ID like SALES-1 but I'm Currently getting DEPT-1 so please help me to fix it with some dynamic id based on Current Input. Thank You all for going through it.

CodePudding user response:

you can agree on the rule that prefix is not the prefix value but property name from which to read value.

so you can do similar to following then:

    final String prefixValue = BeanUtils.getProperty(obj, prefix);
    String query = String.format("select %s from %s", 
        session.getEntityPersister(obj.getClass().getName(), obj).getIdentifierPropertyName(),
        obj.getClass().getSimpleName());

    Stream<String> ids = session.createQuery(query).stream();

    Long max = ids
        .filter( o -> o.startWith(prefixValue))
        .map(o -> o.replace(prefixValue  "-", ""))
        .mapToLong(Long::parseLong)
        .max()
        .orElse(0L);

    return prefixValue   "-"   (max   1);

But consider efficiency of this when you would have a lot of data :) you are constantly fetching all the identities of entities. that is not good.

CodePudding user response:

So you want the prefix to be taken from the dept field of UserModel instance that you're storing, right?

In that case you need to add this to your generate method, e.g.

    @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<String> ids = session.createQuery(query).stream();

        Long max = ids.map(o -> o.replace(prefix   "-", ""))
            .mapToLong(Long::parseLong)
            .max()
            .orElse(0L);
            
        String idPrefix = prefix;
        if(obj instanceof UserModel) {
            UserModel user = (UserModel) obj;
            if(user.getDept() != null && !user.getDept().trim().isEmpty()) {
                idPrefix = user.getDept().trim();
            }
        }

        return idPrefix   "-"   (max   1);
    }

  • Related