我是弹簧和弹簧靴的新手,并且通过开发一个简单的应用程序来玩耍。我有以下用例,如下所述。
我的Spring Boot项目中具有以下类定义。
public class Issue {
@Id
@GenericGenerator(name = "sequence_issue_id", strategy = "com.app.mycompany.AgileCenterServices.util.IssueIdGenerator",
parameters = @Parameter(name = "ProjectKey", value = "PeopleCenter" ))
@GeneratedValue(generator = "sequence_issue_id")
@Column(unique = true)
private String id;
private String projectId;
}
我有一个IssueIdGenerator类,该类将动态值设置为Issue POJO类中的id参数。
但是,在这样做的同时,我想为id参数设置一个前缀。
我应该如何将此动态前缀值发送到IssueIdGenerator类。
前缀值不是固定值,将作为Issue POJO类的属性接收。
因此,我想将此前缀值(在Issue POJO类中作为属性存在)传递给IssueIdGenerator类。
答案 0 :(得分:0)
通过定义自定义生成器,您将更接近(使用生成器)用例。
在https://www.baeldung.com/hibernate-identifiers中可用的示例是:
让我们创建一个生成器,生成包含字符串的标识符 前缀和数字:
public 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");
}
}
>
在此示例中,我们从IdentifierGenerator接口重写了generate()方法,然后首先从 前缀形式为XX的现有主键。
然后,我们在找到的最大数量上加1,并附加前缀 属性以获取新生成的id值。
我们的类还实现了Configurable接口,因此我们可以 在configure()方法中设置前缀属性值。
接下来,让我们将此自定义生成器添加到实体。为此,我们可以 将@GenericGenerator注释与策略参数一起使用 包含我们的生成器类的完整类名:
@Entity
public class Product {
@Id
@GeneratedValue(generator = "prod-generator")
@GenericGenerator(name = "prod-generator",
parameters = @Parameter(name = "prefix", value = "prod"),
strategy = "com.baeldung.hibernate.pojo.generator.MyGenerator")
private String prodId;
// ...
}
另外,请注意,我们已将prefix参数设置为“ prod”。
让我们看一下JUnit快速测试,以更清楚地了解ID 生成的值:
@Test
public void whenSaveCustomGeneratedId_thenOk()
{
Product product = new Product();
session.save(product);
Product product2 = new Product();
session.save(product2);
assertThat(product2.getProdId()).isEqualTo("prod-2");
}
在这里,使用“ prod”前缀生成的第一个值是“ prod-1”,其后是 通过“ prod-2”。
另一种选择是使用复合密钥(JPA规范):
复合主键必须对应于单个持久性键 字段或属性,或一组这样的字段或属性,例如 如下面所描述的。必须定义一个主键类来表示一个 复合主键。复合主键通常在以下情况下出现 当数据库密钥包含以下内容时,从旧数据库进行映射 几列。使用EmbeddedId和IdClass批注 表示复合主键。参见第9.1.14和9.1.15节。