Критерии гибернации при сборе values ​​

Я пытаюсь составить сложный запрос с помощью Hibernate. Я склонялся к критериям, но начинаю подозревать, что это невозможно, поэтому любые предложения будут полезны.

У меня есть структура сущностей, подобная следующей:

public class Attribute {
    private Integer id;
    private String name;
    private Set<Value> values;
}

public class Instance {
    private Integer id;
    private int instanceRef;
    private Set<Value> values;
}

public class Value {
    private Integer id;
    private Attribute attribute;
    private String localAttributeName;
    private Instance instance;
    private String value;
}

Эти сущности связаны так же, как и вы ожидать:

value.attribute_id --> attribute.id
value.instance_id --> instance.id

Теперь, Я хотел бы иметь возможность взять набор пар атрибут / значение (строки) и найти все экземпляры, содержащие все из них. В Value только один из attribute и localAttributeName не равен NULL, поэтому имя атрибута может соответствовать либо localAttributeName, либо attribute.name. И, чтобы еще раз усложнить ситуацию, уникальный индекс для Value находится на (экземпляр, атрибут, значение) или (instance, localAttributeName, value), то есть внутри экземпляра любой заданный атрибут может иметь несколько значений.

Вот что у меня есть на данный момент:

public List<Instance> getMatchingInstances(Map<String, String> attrValues) {
    Criteria crit = session.createCriteria(Instance.class, "i");
    for(Map.Entry<String, String> entry : attrValues) {
        DetachedCriteria valueCrit = DetachedCriteria.forClass(Value.class, "v");

        // Do something here with valueCrit

        crit.add(Subqueries.exists(valueCrit));
    }
    return crit.list();
}

Основываясь на проведенном мною исследовании, я пробовал для этого раздела «Сделай что-нибудь»:

    // This would only check localAttributeName and not attribute.name.
    // That's okay -- once I get the rest to work, I can figure this out.
    valueCrit.add(Restrictions.eq("localAttributeName", entry.getKey());
    valueCrit.add(Restrictions.eq("value", entry.getValue());
    valueCrit.add(Restrictions.eqProperty("v.instance_id", "i.id"));

Но это вызывает исключение ниже, которое, как я подозреваю, говорит мне, что я могу не делайте этого с критериями, но я бы хотел узнать иначе: forwardingTargetForSelector: получает ...

Насколько я понимаю, нереализованный метод разрешается следующим образом:

  1. resolveInstanceMethod: / resolveClassMethod: получает возможность реализовать метод
  2. forwardingTargetForSelector: получает возможность пересылать делегату
  3. forwardInvocation: получает возможность обрабатывать метод так, как он считает нужным.

Где определяется этот трехэтапный процесс? Я бы хотел разобраться с этим сам, поскольку NSInvocation может быть слишком тяжелым для моих нужд. Я ковырялся в источнике среды выполнения и ничего не вижу.

Похоже, что старая среда выполнения вызывала forward: args: на приемнике, чтобы сделать это, но, похоже, это ушло из новой. . Я предполагаю, что процесс должен определяться фреймворком, а не средой выполнения, поскольку он Было бы странно, если бы среда выполнения зависела от Какао до такой степени, что требовал NSInvocation для обработки сообщений. Может быть, это недокументированный метод, который вызывается в NSObject / NSProxy?

Edit:

Похоже, среда выполнения объявляет, но никогда не определяет, функцию C, которая вызывается, когда objc_msgSend не может найти реализацию:

id objc_msgForward (id object, SEL message, ...);

Я не работаю в Apple, поэтому не знаю, как Foundation это реализует, но, по крайней мере, в случае Cocotron они используют:

id objc_msgForward(id object,SEL message,...)
{
   Class       class=object->isa;
   struct objc_method *method;
   void       *arguments=&object;

   if((method=class_getInstanceMethod(class,@selector(forwardSelector:arguments:)))!=NULL)
        return method->method_imp(object,@selector(forwardSelector:arguments:),message,arguments);
   else
   {
       OBJCRaiseException("OBJCDoesNotRecognizeSelector","%c[%s %s(%d)]", class_isMetaClass(class) ? '+' : '-', class->name,sel_getName(message),message);
       return nil;
   }
}

добавление метода forwardSelector: arguments: , похоже, не работает, поэтому я предполагаю, что это характерно только для Cocotron. Кто-нибудь знает, что objc_msgForward делает в Foundation?

6
задан Chris Devereux 29 January 2011 в 18:04
поделиться