JPA Name der konkreten Klasse

Diskutiere Name der konkreten Klasse im Data Tier Forum; Hallo, ich habe mehrere Interfaces, welche das JpaRepository implementieren. Da einige Programmteile identisch sind, habe ich folgende generische...

  1. Saheeda
    Saheeda Aktives Mitglied
    Hallo,

    ich habe mehrere Interfaces, welche das JpaRepository implementieren.
    Da einige Programmteile identisch sind, habe ich folgende generische Methode:

    Code (Java):
        private <T extends Entity<T>, ID extends Serializable> Set<T> translate(final List<ID> list,
                final JpaRepository<T, ID> repository) {

            Set<T> objects = new HashSet<>();
            for (ID t : list) {
                T object = repository.findOne(t);
                if (object == null) {
                    throw new IllegalArgumentException(MessageFormat.format("no object with id {0} found in {1} repository.",
                            t,
                            repository.getClass().getName()));
                }          
                objects.add(object);
            }
            return objects;
        }
    Ich möchte in der Fehlermeldung gern den Namen des konkreten Repositorys (bzw. der Entität) stehen haben. repository.getClass().getName() liefert aber nur "$Proxy1...".

    Hat jemand ne Idee, wie ich die Fehlermeldung bauen kann? Den Repositorynamen als String mit in die Methode hineinzugeben finde ich mehr als nur dreckig :-/.
     
  2. Vielleicht hilft dir das kostenlose Training weiter --> (hier klicken)
  3. stg
    stg Bekanntes Mitglied
    Mir ist nicht klar, was genau du erwartest. Willst du nun den konkreten Typ von T zur Laufzeit wissen, oder welche spezielle Implementierung von JPARepository genau übergeben wird?
    In letzterem Fall wird ja offenbar nicht deine Instanz direkt übergeben, sondern diese wird hinter einem Proxy-Objekt "versteckt". Da musst du nun erstmal herausfinden, wer dafür genau verantwortlich ist und ob das verwendete Framework ggfls auch Möglichkeiten bereitstellt auf das hinter dem Proxy liegende Objekt direkt zuzugreifen.
    Mit Spring kenn ich mich nicht wirklich aus, aber vielleicht hilft dir AOPUtils:
    https://docs.spring.io/spring/docs/...opUtils.html#getTargetClass-java.lang.Object-
    Ist es ein WELD-Proxy, dann kannst du mal probieren die superClass abzufragen
    Code (Text):
    repository.getClass().getSuperClass().getName()
    , aber das ist auch nicht schön.
    Wie man an das Object hinter dem Proxy bekommt hängt wie schon gesagt vom Framework (und der Art und Weise, wie dieser erstellt wird) ab.

    Die einfachste Variante für den ersten Fall wäre die Klasse als Instanzvariable schon im Konstruktor zu setzen. Hab ich auch schon oft gesehen.
    Du kannst dir aber auch ParameterizedType mal anschauen.
     
  4. Saheeda
    Saheeda Aktives Mitglied
    Hi,

    Momentan steht in der Fehlermeldung "no object with id 1 found for $Proxy123". Für eine vernünftige Rückmeldung bzw. um die Fehlersuche zu erleichtern wäre es besser, wenn in der Fehlermeldung auch stehen würde, wo/für welche Entität/in welcher Tabelle der gesuchte Eintrag nicht gefunden werden konnte.
    Ich hätte also gern sowas wie "no object with id 1 found for User" oder "no object with id 1 found for UserRepository". Eben irgendein genauerer Hinweis, welche Parameter des Requests falsch ist.

    Zum JpaRepository selbst gibt es im Code keine konkreten Instanzen, es gibt eigene Interfaces, welche das JpaRepository erweitern, die "Magic" wird von Spring übernommen.
    T wiederum ist der konkrete Typ der Entität/des Domainobjekts, welches durch das Repository verarbeitet wird.

    Code (Java):
    public interface UserRepository extends JpaRepository<User, Long>{

        List<User> findByName(String name);
    }
    Ich hätte jetzt erwartet, dass es irgendwie möglich ist, an "de.blubberblaba.repository.UserRepository" oder "de.blubberblabal.domain.User" heranzukommen.

    Ich hab mir jetzt erstmal so beholfen, finde es aber nach wie vor nicht wirklich schön.
    Code (Java):

    private<T extends Entity<T>, ID extends Serializable> Set<T> translate(final List<ID> list,
               final JpaRepository<T, ID> repository, final Class<T> entityClass){

            Set<T> objects =new HashSet<>();
           for(ID t : list){
                T object = repository.findOne(t);
               if(object ==null){              
                      throw new IllegalArgumentException(MessageFormat.format("no object with id {0} found for {1}.",
                        t,
                        entityClass.getName()));
               }        
                objects.add(object);
           }
           return objects;
       }
     
     
  5. stg
    stg Bekanntes Mitglied
    Mal ganz doof ... was liefert denn
    Code (Text):
    object.getClass()
    zurück?

    Ganz einfacher (und hässlicher :) )Test-Case:

    Code (Java):

      static <T> void doTest(List<T> list) {
          T item = list.get(0);
          System.out.println(item.getClass());
      }
     
      public static void main(String ... args) {
          List<Integer> i = new ArrayList<>();
          i.add(3);
          doTest(i);
      }
     
    Liefert mir als Ausgabe:
    Code (Text):
    class java.lang.Integer
    Das ist doch das, wonach du suchst, wenn ich dich nun richtig verstanden habe?
     
  6. Saheeda
    Saheeda Aktives Mitglied
    Item ist an der Stelle leider null, aber ja, darauf will ich hinaus.
     
  7. stg
    stg Bekanntes Mitglied
    Ja, stimmt, das sit natürlich blöd. Ist mir irgendwie entgangen.
    Ohne eine konkrete Instanz von T zu haben sehe ich dann mit Java-Boardmitteln (auch mit Reflection) keine Möglichkeit an den tatsächlichen Typ von T zu kommen.
    An deiner Stelle würde ich den Weg einschlagen und versuchen herauszufinden, wie Spring die Proxys umsetzt. Im einfachsten Fall geschieht das einfach über Vererbung und ein Aufruf von
    Code (Text):
    repository.getClass().getSuperClass()
    liefert schon das gewünschte zurück (hast du das denn mal probiert?) Geschieht das über Komposition, dann geh doch mal mittels Reflection alle Typen durch, von denen dein Proxy-Objekt ist (das ist etwas schwammig ausgedrückt, hoffentlich verstehst du trotzdem, was ich meine?!) Vielleicht ist da ein passender Typ bei, auf den du dein Proxy casten kannst, auf welchem du eine Methode wie "getTargetClass()" oder ähnliches aufrufen kannst, um direkt auf des "versteckte" Objekt hinter dem Proxy zugreifen zu können.
     
  8. Schau dir jetzt hier den Kurs an und lerne Java zu programmieren: --> Hier klicken, um mehr zu erfahren (Klick)
Die Seite wird geladen...

Name der konkreten Klasse - Ähnliche Themen

Usage: java ZipInfo zfname
Usage: java ZipInfo zfname im Forum Allgemeine Java-Themen
Variable Objektnamen
Variable Objektnamen im Forum Java Basics - Anfänger-Themen
No Persistence provider for EntityManager named X
No Persistence provider for EntityManager named X im Forum Allgemeines EE
Name eines JMenue als Parameter übergeben
Name eines JMenue als Parameter übergeben im Forum Java Basics - Anfänger-Themen
Objekt Name für MethodenAufruf nachträglich zuweisen?
Objekt Name für MethodenAufruf nachträglich zuweisen? im Forum Java Basics - Anfänger-Themen
Thema: Name der konkreten Klasse