具有动态前缀的非 id 列上的序列生成器

问题描述 投票:0回答:1

我对 Spring Data JPA 还很陌生。我想在非 id 列上生成序列,该列具有前缀,但前缀可以在运行时更改。

例如,如果用户输入“A”,那么数据将是“A00001”...并且继续像 A00002、A00003,但用户可以输入“B”、“C”...那么数据将是“B00001”、“B00002”。

实体:

@Entity
public class UserEntity extends BaseTimeEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(nullable=false, length=20)
    private String role;

    @GeneratorType(type=CustomGenerator.class,when= GenerationTime.INSERT)
    @Column(nullable=false, length=45, unique = true, updatable = false)
    private String loginId;
}

自定义生成器:

public class CustomGenerator implements ValueGenerator<String> {
    private static final String query = "SELECT CONCAT('A',COALESCE(MAX((SUBSTR(LOGIN_ID,3))),10000)+1) FROM USER WHERE INSTR(LOGIN_ID, 'A')>0";

    @Override
    public String generateValue(Session session, Object o) {

        NativeQuery nativeQuery = session.createSQLQuery(query);
        String loginId = (String) nativeQuery.setFlushMode(COMMIT).uniqueResult();
        return loginId;
    }
}

在这篇文章的一些帮助下,我弄清楚了如何在非 id 列上生成序列(如何为非 ID 字段使用序列生成器?),但仍然不知道如何动态更改前缀。

java jpa
1个回答
0
投票

我有一个类似的问题,但条件是前缀取决于实体类型,并带有-月-年后缀。所以我的解决方案是:

@Getter
@AllArgsConstructor
public enum EntityType {
  INNER("I", "inner_number_sequence"),
  EXTERNAL("Е", "external_number_sequence");

  private final String prefix;
  private final String sequence;
}

@Override
public String generateValue(Session session, Object object) throws HibernateException {
  if (!(object instanceof MyEntity)) {
    throw new CastException("Incorrect cast...");
  }
  EntityType type = ((MyEntity) object).getType();

  String nextSeqValue = String.format("select nextval('%s');", type.getSequence());
  @SuppressWarnings("unchecked")
  NativeQuery<BigInteger> query = session.createNativeQuery(nextSeqValue);
  Long sequenceValue = query.setHibernateFlushMode(COMMIT).uniqueResult().longValue();

  String postfix = LocalDate.now().format(DateTimeFormatter.ofPattern("-MM-yy"));
  return type.getPrefix() + String.format("%05d", sequenceValue) + postfix;
}

我想没有什么可以阻止你将用户的字母放置到“loginId”中,并将其与类转换后的序列连接起来,如我的示例所示。

© www.soinside.com 2019 - 2024. All rights reserved.