gpt4 book ai didi

java - 如何让 Morphia 将字段的值设置为函数调用的返回值?

转载 作者:太空宇宙 更新时间:2023-11-04 06:19:09 24 4
gpt4 key购买 nike

我正在使用此处描述的策略实现“自动增量”id: http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/

基本上,seqId 字段的值是通过调用实用程序函数来设置的,该函数更新辅助集合上的计数器并返回递增的值。听起来不错。

我的问题是映射它以与 Morphia 一起使用。本教程建议像这样执行插入(例如在 shell 中):

db.users.insert(
{
seqId: getNextSequence("userid"),
name: "Sarah C."
}

我基本上想做一些事情,比如将 POJO seqId 字段设置为当我调用 save() 时 Morphia 会将其转换为类似于上面的插入内容的内容。

我的 POJO 看起来像这样:

@Entity
public class User {

@Id
private Long id;

// THIS IS THE FIELD I WANT TO AUTO-INCREMENT
private Long seqId;

private String name;

...
}

问题是:如何让 Morphia 将字段的值设置为函数调用的返回值?

我研究了使用 @PrePresist 注释来执行此函数调用并获取值,然后将其设置在 +_id 字段中。这有几个缺点,例如多次调用 MongoDB 而不是一次,而且我的模型对象没有对数据存储的引用,我不想混淆这些问题。

这可能吗?有什么建议吗?

我使用最新的 Java 驱动程序,使用 MongoDB 2.6.6。

谢谢!

PS:我知道在大型环境中不建议使用自动增量。无论如何,对于这个特定场景我需要它。

最佳答案

我将描述对我们来说非常有效的解决方案。请注意,这支持类级别及其子集的自动增量 - 因此您可以计算用户或管理员用户(具有管理员枚举或其他内容的用户)。

这包含每个自动增量字段的当前值,它基本上是一个引用:

@Entity(noClassnameStored = true)
public class AutoIncrementEntity {

@Id
protected String key;

protected Long value = 1L;

protected AutoIncrementEntity() {
super();
}

/**
* Set the key name — class or class with some other attribute(s).
*/
public AutoIncrementEntity(final String key) {
this.key = key;
}

/**
* Set the key name and initialize the value so it won't start at 1.
*/
public AutoIncrementEntity(final String key, final Long startValue) {
this(key);
value = startValue;
}

public Long getValue() {
return value;
}
}

在持久化服务中,您可以使用以下命令自动设置/创建自动增量:

public <E extends BaseEntity> ObjectId persist(E entity) {

// If it's a user and doesn't yet have an ID, set one; start counting from 1000.
if ((entity instanceof UserEntity) && (((UserEntity) entity).getUserId() == null)) {
((UserEntity) entity).setUserId(
generateAutoIncrement(entity.getClass().getName(), 1000L));
}

// Additionally, set an ID within each user group; start counting from 1.
if ((entity instanceof UserEntity) && (((UserEntity) entity).getRoleId() == null)) {
((UserEntity) entity).setRoleId(
generateAutoIncrement(entity.getClass().getName() + "-" + entity.getRole(), 1L));
}

mongoDataStore.save(entity);
return entity.getId();
}

/**
* Return a unique numeric value for the given key.
* The minimum value, set to 1 if nothing specific is required.
*/
protected long generateAutoIncrement(final String key, final long minimumValue){

// Get the given key from the auto increment entity and try to increment it.
final Query<AutoIncrementEntity> query = mongoDataStore.find(
AutoIncrementEntity.class).field("_id").equal(key);
final UpdateOperations<AutoIncrementEntity> update = mongoDataStore
.createUpdateOperations(AutoIncrementEntity.class).inc("value");
AutoIncrementEntity autoIncrement = mongoDataStore.findAndModify(query, update);

// If none is found, we need to create one for the given key.
if (autoIncrement == null) {
autoIncrement = new AutoIncrementEntity(key, minimumValue);
mongoDataStore.save(autoIncrement);
}
return autoIncrement.getValue();
}

最后是你的实体:

@Entity(value = "user", noClassnameStored = true)
public class UserEntity extends BaseEntity {

public static enum Role {
ADMIN, USER,
}

private Role role;

@Indexed(unique = true)
private Long userId;

private Long roleId;

// Role setter and getter

public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}

public Long getRoleId() {
return roleId;
}
public void setRoleId(Long roleId) {
this.roleId = roleId;
}

}

实体中没有发生任何具体的事情。所有逻辑均由持久性服务处理。我没有使用 @PrePersist,因为您需要将持久性服务放入实体中,这听起来不是一个好主意。

关于java - 如何让 Morphia 将字段的值设置为函数调用的返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27662561/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com