2017-04-07 3 views
1

Je suis un peu coincé et je ne comprends pas ce qui se passe. Celui-ci ne fonctionne pasJPA et classes "anonymes" en scala

@Entity 
@DynamicInsert 
@DynamicUpdate 
@SelectBeforeUpdate 
@Table 
class Entity { 
    @Column(nullable = false) 
    var owner: String = _ 
} 


    val myEntity = new Entity() { 
      owner = "some owner 1" 
      } 
     session.persist(myEntity) 

Hibernate lance exception:

java.lang.IllegalArgumentException: Unknown entity:persistence.dao.EntityDaoTest$$anonfun$13$$anonfun$14$$anon$5 
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:777) 

Celui-ci fonctionne:

val myEntity = new Entity() 
entity.owner = "some owner 1" 
session.persist(myEntity) 

Pourquoi? Pourquoi hibernate ne reconnaît pas mon instance Entity?

UPD: @Sheinbergon, merci, c'est clair. J'ai complètement oublié que les annotations sont perdues. Est-il possible de définir des champs d'entité avec un raccourci? écriture

val myEntity = new MyEntity() 
myEntity.owner = "some owner" 
myEntity.someOtherProperty = "value" 

est super ennuyeux

Une question Celui-ci fonctionne:

val parent = new Parent 
    parent.owner = "Our parent" 
    parent.addChild(new Child() { 
     name = "First parent's child" 
     addGrandChild(new GrandChild() { 
     name = "Grand child name" 
     addGrandGrandChild(new GrandGrandChild() { 
      name = "Grand Grand child name" 
      address = new Address() { 
      id = 1L 
      } 
     }) 
     }) 
    }) 

Pourquoi? Enfant, GrandChild, GrandGrandChild également créé anonymement. addChild, addGrandChild, addGrandGrandChild ne sont que des mutateurs de liste.

def addChild(child: Child): Unit = { 
    if (children == null) { 
     children = new util.ArrayList[Child]() 
    } 
    if (Option(child.parent).isEmpty) { 
     child.parent = this 
    } 
    children.add(child) 
    } 
+1

S'il vous plaît "accepter" ma réponse (l'un d'entre eux) comme il vous a aidé. J'ai ajouté une autre section à la réponse ci-dessous qui se rapporte aux nouvelles sous-questions que vous avez soulevées – Sheinbergon

+0

Fait, merci!Maintenant c'est clair – Sergey

Répondre

2

Ce que vous faites ici est instancié une classe anonyme à Scala, et bien ... qui crée une implémentation anonyme de votre classe Entity (comme instancier une interface anonyme en Java).

vous pouvez le voir en imprimant le nom de classe - println(myEntity.getClass) dans les deux cas

annotations appliquées à la classe d'origine ne valent pas une anonyme (réflexion peut les trouver encore dans la super classe, mais c'est jusqu'à le code les numérisant) et je pense que c'est la raison pour laquelle vous obtenez les diverses exceptions JPA

En réponse à vos sous-questions ajoutées

  • En ce qui concerne un raccourci - pourquoi n'utilisez-vous pas des objets compagnons pour les usines ou transformez cette classe en classe de cas (avec des valeurs par défaut), permettant une initialisation plus agréable et plus flexible. En ce qui concerne le deuxième graphe d'objet (et en supposant que chacune de vos classes est annotée), cela dépend encore de la façon dont le code réfléchissant traite les objets qu'il analyse. il est possible (et plus probable, étant donné qu'il n'analysera pas chaque membre de la collection pour les annotations) il prend des définitions d'annotation du type effacé (possible d'obtenir son nom de classe FQDN comme ParameterizedType dans l'API de réflexion Java) de la collection et non des membres réels de la collection et c'est pourquoi cela fonctionne. Je ne suis pas vraiment sûr de ce qu'il fait des définitions de champs (elles ne sont présentes que dans la classe "super"), mais il n'y a pas de "magie" ici, juste de vieilles analyses de réflexion.
+1

Il n'y a pas de fonction anonyme ici, et ce n'est pas "sorte de" mais exactement comme une classe Java anonyme (qui peut aussi étendre les classes). Sinon correct. –

+1

Le 'anonfun' dans les noms de classe est parce que ce code est _inside_ une fonction anonyme non-montrée. –

+1

@AlexeyRomanov merci pour vos commentaires, j'ai affiné ma réponse :) – Sheinbergon