2011-11-11 6 views
6

Próbuję zrozumieć, w jaki sposób dziedziczenie działa w grze! Ale bezskutecznie jeszcze.Jak odziedziczyć model z nadklasy w strukturze Playframework

Tak, mam takie superklasę:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
abstract class SuperClass extends Model { 
    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "SEQ_TABLE") 
    @TableGenerator(name = "SEQ_TABLE") 
    Long id; 

    int testVal; 
} 

oraz 2 dziedziczone klasy:

@Entity 
public class Sub extends SuperClass {   
    String name; 

    @Override 
    public String toString() { 
      return name; 
    } 
} 

@Entity 
public class Sub1 extends SuperClass {   
    String name; 

    @Override 
    public String toString() { 
      return name; 
    } 
} 

Również mam 2 kontrolerów dziedzicznych klas:

public class Subs and Sub1s extends CRUD { 

} 

Po zgłoszenie zostało rozpoczęte , Otrzymuję 2 tabele w MySQL db dla moich modeli (Sub i Sub1) o takiej strukturze: id bigint (20), nazwa varchar (255). Bez testu testVal, który znajduje się w nadklasie.

I gdy próbuję utworzyć nowy obiekt Sub klasy w interfejsie CRUD I odbieranie taki błąd: błąd Wykonanie wystąpił w szablonie {moduł: CRUD} /app/views/tags/crud/form.html. Podniesiono wyjątek: MissingPropertyException: Brak takiej właściwości: testVal dla klasy: models.Sub.

w {modułu: CRUD} /app/views/tags/crud/form.html (64) wokół linii # {crud.numberField nazwisko: field.name, wartość: (currentObject currentObject [pola .name]: null) /}

  1. Co należy zrobić, aby wygenerować tabel MySQL do odziedziczonych modeli prawidłowo i naprawić ten błąd?
  2. Czy jest możliwe posiadanie jednego superControllera dla kilku dziedziczonych klas?
+1

Pamiętaj, że deklarujesz swoje pola za pomocą domyślnego modyfikatora dostępu. Zmień to na publiczne, aby gra PropertiesEnhaner mogła wykonać swoją pracę. – sdespolit

+0

Dziękuję. Dodałem publiczny dostęp do 'Long id' i' int testVal'. Teraz widzę pole testVal w interfejsie CRUD i mogę zapisać model bez błędów. Ale wciąż nie ma takiego pola w MySql, więc nie mogę zapisać tej wartości. Uważam, że powinienem dodać jakąś adnotację do tej wartości, ale co? – gl0om

+0

Wreszcie znalazłem rozwiązanie: Właśnie dodałem '@ MappedSuperclass' do' SuperClass' i usunąłem 'Long id' z niego. ** sdespolit **, jak zaakceptować sugestię dodania środka pośredniczącego do dostępu publicznego? Nie mogę znaleźć przycisku akceptacji. – gl0om

Odpowiedz

2

Cóż, dzięki sdespolit, zrobiłem kilka eksperymentów. A oto co mam:

Nadklasa:

@MappedSuperclass 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public abstract class SuperClass extends Model { 
} 

dziedziczone klasy:

@Entity 
public class Sub extends SuperClass { 
} 

"Super Controller" zrobiłem w taki sposób:

@With({Secure.class, SuperController.class}) 
@CRUD.For(Sub.class) 
public class Subs extends CRUD { 
} 

@With({Secure.class, SuperController.class}) 
@CRUD.For(Sub1.class) 
public class Sub1s extends CRUD { 
} 

@ CRUD.For (Sub.klasa) służy powiedzieć przechwytujących z jakiej klasy to powinno działać

public class SuperController extends Controller { 

    @After/Before/Whatever 
    public static void doSomething() { 
     String actionMethod = request.actionMethod; 
     Class<? extends play.db.Model> model = getControllerAnnotation(CRUD.For.class).value(); 

     List<String> allowedActions = new ArrayList<String>(); 
     allowedActions.add("show"); 
     allowedActions.add("list"); 
     allowedActions.add("blank"); 

     if (allowedActions.contains(actionMethod)) { 
      List<SuperClass> list = play.db.jpa.JPQL.instance.find(model.getSimpleName()).fetch(); 
     } 
    } 
} 

nie jestem pewien o doSomething() podejście jest naprawdę ładny i Java-style/Play! -Style. Ale to działa dla mnie. Proszę mi powiedzieć, czy da się wychwycić klasę modelu w bardziej natywny sposób.

1

"i tabela na klasę jest opcjonalną funkcją specyfikacji JPA, więc nie wszyscy dostawcy mogą ją wspierać" od WikiBook.

Dlaczego nie używasz @MappedSuperclass? Ponadto powinieneś rozszerzyć GenericModel. W twoim przykładzie zdefiniowałeś identyfikator dwa razy, co może być również przyczyną twojego problemu.