Как получить имя поля @Field (org.springframework.data.mongodb.core.mapping.Field) из имени класса? [Дубликат]

Добавление случая, когда имя класса для объекта, используемого в структуре сущности, такое же, как имя класса для файла с кодировкой веб-формы.

Предположим, у вас есть веб-форма Contact.aspx, чей класс codebehind Свяжитесь с вами, и у вас есть имя объекта Contact.

Затем следующий код вызовет исключение NullReferenceException при вызове context.SaveChanges ()

Contact contact = new Contact { Name = "Abhinav"};
var context = new DataContext();
context.Contacts.Add(contact);
context.SaveChanges(); // NullReferenceException at this line

Ради полноты класса DataContext

public class DataContext : DbContext 
{
    public DbSet Contacts {get; set;}
}

и класс сущности контакта. Иногда классы сущностей являются частичными классами, так что вы можете распространять их и в других файлах.

public partial class Contact 
{
    public string Name {get; set;}
}

Ошибка возникает, когда оба класса entity и codebehind находятся в одном и том же пространстве имен. Чтобы исправить это, переименуйте класс сущности или класс codebehind для Contact.aspx.

Причина. Я все еще не уверен в причине. Но всякий раз, когда какой-либо из классов сущностей расширяет System.Web.UI.Page, возникает эта ошибка.

Для обсуждения рассмотрим NullReferenceException в DbContext.saveChanges ()

77
задан darioo 28 November 2010 в 14:19
поделиться

7 ответов

Да, если в аннотации Column есть сохранение времени выполнения

@Retention(RetentionPolicy.RUNTIME)
@interface Column {
    ....
}

, вы можете сделать что-то вроде этого

for (Field f: MyClass.class.getFields()) {
   Column column = f.getAnnotation(Column.class);
   if (column != null)
       System.out.println(column.columnName());
}
91
ответ дан Dori 28 August 2018 в 08:42
поделиться

Конечно. Ниже приведен пример аннотации:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {

    String testText();
}

И пример аннотированного метода:

class TestClass {

    @TestAnnotation(testText="zyx")
    public void doSomething() {}
}

И образец метода в другом классе, который печатает значение testText:

Method[] methods = TestClass.class.getMethods();
for (Method m : methods) {
    if (m.isAnnotationPresent(TestAnnotation.class)) {
        TestAnnotation ta = m.getAnnotation(TestAnnotation.class);
        System.out.println(ta.testText());
    }
}

Не так много для аннотаций полей, как ваш.

Cheerz!

69
ответ дан Dumbo 28 August 2018 в 08:42
поделиться
4
ответ дан Fritz Duchardt 28 August 2018 в 08:42
поделиться

В общем случае у вас есть частный доступ для полей, поэтому вы НЕ МОЖЕТЕ использовать getFields в отражении. Вместо этого вы должны использовать getDeclaredFields

Итак, во-первых, вам следует знать, имеет ли аннотация в столбце сохранение времени выполнения:

@Retention(RetentionPolicy.RUNTIME)
@interface Column {
}

После этого вы можете сделать что-то вроде этого:

for (Field f: MyClass.class.getDeclaredFields()) {
   Column column = f.getAnnotation(Column.class);
       // ...
}

Очевидно, что вы хотите сделать что-то с полем - установите новое значение, используя значение аннотации:

Column annotation = f.getAnnotation(Column.class);
if (annotation != null) {
    new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke(
        object,
        myCoolProcessing(
            annotation.value()
        )
    );
}

Итак, полный код может выглядеть так:

for (Field f : MyClass.class.getDeclaredFields()) {
    Column annotation = f.getAnnotation(Column.class);
    if (annotation != null)
        new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke(
                object,
                myCoolProcessing(
                        annotation.value()
                )
        );
}
1
ответ дан Oleg Poltoratskii 28 August 2018 в 08:42
поделиться

Вы также можете использовать общие типы, в моем случае, принимая во внимание все сказанное, прежде чем вы сможете сделать что-то вроде:

public class SomeTypeManager<T> {

    public SomeTypeManager(T someGeneric) {

        //That's how you can achieve all previously said, with generic types.
        Annotation[] an = someGeneric.getClass().getAnnotations();

    }

}

Помните, что это не будет эквивалентно 100% для SomeClass.class .get (...) ();

Но может сделать трюк ...

2
ответ дан SigmaSoldier 28 August 2018 в 08:42
поделиться

Я никогда этого не делал, но это выглядит как Reflection . Field является AnnotatedElement и поэтому имеет getAnnotation . На этой странице приведен пример (скопировано ниже); довольно просто, если вы знаете класс аннотации, и если в аннотационной политике сохраняется аннотация во время выполнения. Естественно, если политика хранения не сохраняет аннотацию во время выполнения, вы не сможете запросить ее во время выполнения.

Ответ, который был удален (?), Предоставил полезную ссылку на учебник аннотаций , который может оказаться полезным; Я скопировал ссылку здесь, чтобы люди могли ее использовать.

Пример из этой страницы :

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno {
  String str();

  int val();
}

class Meta {
  @MyAnno(str = "Two Parameters", val = 19)
  public static void myMeth(String str, int i) {
    Meta ob = new Meta();

    try {
      Class c = ob.getClass();

      Method m = c.getMethod("myMeth", String.class, int.class);

      MyAnno anno = m.getAnnotation(MyAnno.class);

      System.out.println(anno.str() + " " + anno.val());
    } catch (NoSuchMethodException exc) {
      System.out.println("Method Not Found.");
    }
  }

  public static void main(String args[]) {
    myMeth("test", 10);
  }
}
19
ответ дан T.J. Crowder 28 August 2018 в 08:42
поделиться
3
ответ дан thundear 28 August 2018 в 08:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: