индексная аннотация с morphia не работает

Я новичок в морфии и изо всех сил пытаюсь заставить работать аннотацию индекса. Я создаю источник данных в статическом блоке и вызываю в том же блоке sureIndexes, но не удается применить индексы. Если я поставлю строку прямо перед сохранением объекта, он сработает.

Кстати, я использую playframework 2 с Java.

public class MongoService {
static private MongoClient mongoClient = null;
static Datastore ds = null;

static {
    MorphiaLoggerFactory.reset();
    MorphiaLoggerFactory.registerLogger(com.google.code.morphia.logging.slf4j.SLF4JLogrImplFactory.class);
    try {
        Logger.debug("mongo uri:" + mongoUri);
        MongoClientURI uri = new MongoClientURI(mongoUri);
        mongoClient = new MongoClient(uri);
        ds =  new Morphia().createDatastore(mongoClient, dbname);
        ds.ensureIndexes();
        ds.ensureCaps();
    }catch(Exception e) {
        Logger.error("exception:" + e.fillInStackTrace());
    }

}

public static User insertUser(User user) {
    //ds.ensureIndexes(); //UNCOMMENTING THIS LINE MAKES IT WORK
    ds.save(user);
    return user;
}

Это реализация пользовательского класса:

@Entity(noClassnameStored = true)
public class User {

@Id private ObjectId id;

@Indexed(value=IndexDirection.ASC, name="email", unique=true, dropDups=true) 
public String email; 
}

person nightograph    schedule 20.07.2013    source источник


Ответы (5)


Вам нужно сопоставить классы сущностей - либо по пакету, либо по классу:

ds = new Morphia().mapPackage("com.test.entities").createDatastore(mongoClient, dbname);
person xeraa    schedule 20.07.2013
comment
я добавил следующую строку ds = new Morphia().mapPackage(models).createDatastore(mongoClient, dbname); models - это игровой пакет по умолчанию для моделей, и где находится мой пользовательский класс, но я получаю это исключение: com.google.code.morphia.mapping.MappingException: не удалось получить классы карт из моделей пакетов. - person nightograph; 20.07.2013
comment
и когда я добавляю эту строку: ds = new Morphia().map(User.class).createDatastore(mongoClient, dbname); проблема существует, morphia не учитывает idnexes - person nightograph; 20.07.2013
comment
Я никогда не работал с Play, поэтому не знаю, как это исправить. Я предполагаю, что new Morphia().mapPackage(YourEntity.class.getPackage().getName()).createDatastore(mongoClient, dbname); тоже не работает? - person xeraa; 21.07.2013
comment
я предполагаю, что что-то не так с загрузчиком классов, который не может найти пакет, это должен быть конфликт между загрузчиком пакетов, который использует play, и тем, который morphia пытается использовать - person nightograph; 26.07.2013
comment
Использование mapPackage, а затем использование datastore.ensureIndexes() решили мою проблему. (Хотя я не использую playframework.) - person a.b; 28.02.2014
comment
Я использую игровую среду, и с этим проблем нет, я решил свои проблемы. Спасибо! - person hiamex; 29.07.2015

Кажется, существует конфликт между загрузчиком пакетов, который использует Morphia, и тем, который пытается использовать play framework, я не смог найти точную проблему, но в качестве обходного пути я сопоставляю каждый объект один за другим, и это, кажется, работает

 morph.map(User.class);
 morph.map(Address.class);
 . 
 . 
 . 
person nightograph    schedule 25.07.2013
comment
Спасибо за этот ответ ... мне потребовалось некоторое время, чтобы понять, что происходит. Более явное решение в соответствии с тем, что вы делаете, состоит в том, чтобы обеспечить индексы для всех классов, которые имеют аннотацию @Indexed, например: ds.ensureIndexes(User.class, false). Последний параметр указывает, происходит ли построение индекса в фоновом режиме. - person Vladimir Ivanov; 05.02.2014

Это мой код в Play, и он работает. Пожалуйста попробуйте:

 modelClass = Class.forName(model, true, app.classloader());
 morphia.map(modelClass);
person Byron Zhang    schedule 16.07.2015

Хотя для OP это не было проблемой, я обнаружил, что, хотя декоратор класса @Entity является необязательным, если его не учитывать, Morphia не создает индексы на уровне поля.

person Ash Eldritch    schedule 02.05.2018

Я решил проблему в этой форме:

public void create(Producto p) {
        Morphia m =new Morphia();
        Datastore ds = m.mapPackage("ec.edu.espe.as.model.Producto").createDatastore(new MongoClient(), "productoPrueba");              
        DBObject dbo = m.toDBObject(p);        
        ds.ensureIndexes();
        ds.getCollection(Producto.class).insert(dbo);
    }

Я имею в виду, что makeIndexes как раз перед вставкой

person jhonatan L M    schedule 13.12.2018