栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

将自定义标识符分配给@id属性

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

将自定义标识符分配给@id属性

我认为不存在使用纯JPA-2
API使用自定义注释生成自定义ID的现成支持。但是,如果要使用提供程序特定的API,则工作非常简单。样例

要独立于提供程序,请尝试以下任何技巧。

IdGeneratorHolder

public abstract class IdGeneratorHolder {        public static IdGenerator getIdGenerator(Class<? extends PersistentEntity> entityType) {          if(Product.class.isAssignableFrom(entityType)) { return new ProductIdGenerator();        }        return null;    }}

常规IdGenerator接口

public interface IdGenerator {    String generate();}

特定IdGenerator-产品ID生成器

public class ProductIdGenerator implements IdGenerator {    public String generate() {         return ${generatedId};    }}

现在, 在无参数构造函数@PrePersist方法中 设置生成的ID 。

产品.java

public class Product implements PersistentEntity {    private String id;    public Product() {        id = IdGeneratorHolder.getIdGenerator(getClass()).generate();    }    @PrePersist    public void generateId() {        id = IdGeneratorHolder.getIdGenerator(getClass()).generate();    }}

在上述示例中,所有ID均为相同类型,即

java.lang.String
。如果持久性实体具有不同类型的ID .....

IdGenerator.java

public interface IdGenerator {    CustomId generate();}

CustomId.java

   public class CustomId {    private Object id;    public CustomId(Object id) {        this.id = id;    }    public String  toString() {        return id.toString();    }    public Long  toLong() {        return Long.valueOf(id.toString());    }}

Item.java

@PrePersist    public void generateId() {        id = IdGeneratorHolder.getIdGenerator(getClass()).generate().toLong();    }

您还可以使用自定义注释…

CustomIdGenerator.java

public @interface CustomIdGenerator {    IdStrategy strategy();}

IdStrategy.java

  enum IdStrategy {        uuid, humanReadable,        }

IdGeneratorHolder.java

public abstract class IdGeneratorHolder {    public static IdGenerator getIdGenerator(Class<? extends PersistentEntity> entityType) {        try { // again sample implementation Method method = entityType.getMethod("idMethod"); CustomIdGenerator gen = method.getAnnotation(CustomIdGenerator.class); IdStrategy strategy = gen.strategy(); return new ProductIdGenerator(strategy);        }

还有一件事....如果我们在@PrePersist方法中设置id,equals()方法将不能依赖id字段(即代理键),则必须使用业务/自然键来实现equals()方法。但是,如果我们在no-
arg构造函数中将id字段设置为某个唯一值(uuid或“ app-uid”在应用程序内是唯一的),则它有助于我们实现equals()方法。

public boolean equals(Object obj) {        if(obj instanceof Product) { Product that = (Product) obj; return this.id ==that.id;        }        return false;    }

如果我们或其他人(故意或错误地)调用@PrePersist带注释的方法多次,则“唯一ID将被更改!!!” 因此,最好在no-
arg构造函数中设置id。或为解决此问题,请放置不为null的检查…

  @PrePersist    public void generateId() {        if(id != null) id = IdGeneratorHolder.getIdGenerator(getClass()).generate();    }}

更新

如果将id生成放入无参数构造函数中,那么从数据库中加载实体时不会造成问题吗?因为hibernate将调用no-arg构造函数,导致现有ID重新生成

是的,您是对的,我错过了这一部分。:(实际上,我想告诉您:-在我的应用程序中,每个Entity对象都与Organization
Entity相关联;因此,我创建了一个具有两个构造函数的抽象超类,每个Entity(除Organization之外)都扩展了该类。

    protected PersistentEntityImpl() {    }    protected PersistentEntityImpl(Organization organization) {        String entityId = UUIDGenerator.generate();        String organizationId = organization.getEntityId();        identifier = new EntityIdentifier(entityId, organizationId);    }

no-arg构造函数用于JPA提供程序,我们从不调用no-
arg构造函数,而是调用其他基于组织的构造函数。如你看到的。id是在基于组织的构造函数中分配的。(我真的在写答案时错过了这一点,对此表示抱歉)。

查看您是否可以在应用程序中实现此策略或类似策略。

第二个选项是使用@PrePersist批注。我把它放进去,该方法从未被击中,并给了我一个例外,指出我需要手动设置id。还有什么我应该做的吗?

理想情况下,JPA提供程序应在持久化实体对象之前调用@PrePersist方法(在类中声明的一个方法,以及在超类中声明的所有其他方法)。除非显示一些代码和控制台,否则无法告诉您出什么问题了。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/415530.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号