2014-12-26 5 views
1

여기에 설명 : http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/Morphia가 함수 호출에서 반환 된 값으로 필드 값을 설정하는 방법은 무엇입니까? 내가 전략을 사용하여 "자동 증가"ID를 구현하고있어

기본적으로 seqId 필드의 값은 보조 컬렉션 카운터를 업데이트하고 증가 반환하는 유틸리티 함수를 호출하여 설정 값. 훌륭해.

제 문제는 Morphia와 함께 사용하기 위해이 문제를 매핑하는 것입니다. 이 튜토리얼과 같이 (예 : 쉘에서와 같이) 삽입을 수행 제안 :

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

나는 기본적으로 모르핀 위의 같은 인서트로 번역 무언가에 POJO seqId 필드를 설정하는 식으로 뭔가를 찾고 있어요 내가 save()을 호출 할 때.

내 POJO는 다음과 같습니다

@Entity 
public class User { 

    @Id 
    private Long id; 

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

    private String name; 

    ... 
} 

질문은 : 어떻게 모르핀은 함수 호출에 의해 반환되는 값으로 필드의 값을 설정하기 위해?

이 함수 호출을 수행하고 값을 얻은 다음 @PrePresist 주석을 사용하여 + _id 필드에 설정했습니다. MongoDB를 하나만 호출하는 대신 여러 번 호출하는 것, 내 모델 객체가 데이터 저장소에 대한 참조를 가지고 있지 않다는 점을 감안할 때 몇 가지 단점이 있습니다.

이것이 가능합니까? 어떤 제안?

최신 Java 드라이버를 사용하여 MongoDB 2.6.6을 사용 중입니다.

감사합니다.

추신 : 대용량 환경에서는 자동 증가가 권장되지 않습니다. 이 특정 시나리오에 대해서는 어쨌든 필요합니다.

답변

1

나는 우리를 위해 아주 잘 작동하는 해결책을 설명 할 것이다. 이 기능은 클래스 수준 및 그 하위 집합에 대한 자동 증가를 지원하므로 사용자 또는 관리자 (사용자가 관리 열거 형 등)를 셀 수 있습니다.

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(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; 
    } 
} 

, 당신은 자동으로 자동 증가를 생성/설정하려면 다음을 사용할 수

이 각 자동 증가 필드의 현재 값을 포함

, 그것은 기본적으로 참조입니다

그리고 마지막으로 당신의 엔티티 : 아무것도 특검팀은

@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을 사용하지 않습니다. 왜냐하면 영속성 서비스를 엔터티에 넣어야하기 때문에 좋은 생각처럼 들리지는 않습니다.

+0

감사합니다. 나는 현재 그 첫 번째 서버 왕복없이 내가 원하는 것을 성취 할 방법이 없다고 생각하지만 이것은 "엔티티 객체의 데이터 저장소"문제에 대한 좋은 해결 방법입니다. –