JPA Syntax error - falscher Aufbau?

Cypha

Mitglied
Hallo zusammen,

ich habe gerade ein Problem im Umgang mit JPA / Hibernate in Verwendung mit der Derby DB.
Der Beispielaufbau ist wie folgt: Es gibt Benutzer und Ordner. Benutzer können auf Ordner berechtigt werden mit den Benutzerrechten UPLOAD, DOWNLOAD und BOTH, welche in einem enum stecken.

Die Objekte habe ich folgendermaßen aufgebaut:

Java:
@Entity
@Table(name = "T_FOLDER_USER_REL")
public class FolderUserRelDO implements Serializable {

   @Id
   private Long              userId;
   @Id
   private Long              folderId;
   @Id
   @Enumerated(EnumType.STRING)
   private AccessRight       right;

// Constructor, getter, setter ausgelassen

Java:
@Entity
@Table(name="T_USER")
public class UserDO implements Serializable {

   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   private Long   id;

   @Column(nullable = false)
   private String login;
   
   @Column(nullable = false)
   private String password;
   
// Constructor, getter, setter ausgelassen

Java:
@Entity
@Table(name = "T_FOLDER")
public class FolderDO implements Serializable {

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Long                  id;
   private Long                  ownerId;
   private String                name;
 
   @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
   @JoinColumn(name = "folderId")
   private Set<FolderUserRelDO>  userPermissions;

// Constructor, getter, setter ausgelassen


Versuche ich nun, einen neuen Ordner ohne Berechtigungszuordnungen zu speichern, fliegt eine Exception:
Java:
public void saveFolder(final FolderDO folder) {
      EntityManager em = factory.createEntityManager();
      em.getTransaction().begin();
      em.merge(folder);
      em.getTransaction().commit();
      em.close();
   }

Java:
Caused by: ERROR 42X01: Syntax error: Encountered "right" at line 1, column 294.
	at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
	at org.apache.derby.impl.sql.compile.ParserImpl.parseStatement(Unknown Source)
	at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source)
	at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source)
	at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(Unknown Source)
	... 66 more

Meine Fragen wären nun:
  • Ist der Aufbau falsch (eventuell die OneToMany Relation o.Ä.)?
  • Gibt es andere grundsätzliche Fehler, die ich gemacht habe? Ich habe mit JPA noch nicht so viel Erfahrung.

Vielen Dank im Voraus!
 
Einen grundsätzlichen Fehler sehe ich. In der Klasse FolderUserRelDO versuchst Du die Beziehung direkt über Ids zu machen. Das ist Datenbankmethodik und entspricht nicht dem Konzept von OO. In Java stellst Du Beziehungen direkt über die Instanzvariablen vom richtigen Typ her. Außerdem ist nach meinem Verständnis das AcessRight nicht Bestandteil der eindeutigen Id. Die wird bereits über die Kombination von User/Folder ausgedrückt. Ändere also den Code wie folgt:
Java:
@Entity
@Table(name = "T_FOLDER_USER_REL")
public class FolderUserRelDO implements Serializable {
 
   @Id
   private UserDO user;

   @Id
   private FolderDO  folder;
   
   @Enumerated(EnumType.STRING)
   private AccessRight       right;
 
Einen grundsätzlichen Fehler sehe ich. In der Klasse FolderUserRelDO versuchst Du die Beziehung direkt über Ids zu machen. Das ist Datenbankmethodik und entspricht nicht dem Konzept von OO. In Java stellst Du Beziehungen direkt über die Instanzvariablen vom richtigen Typ her.
Vielleicht habe ich hier von der falschen Seite aus gedacht. Aus deiner Beschreibung würde ich folgenden Aufbau herleiten:

Java:
public class FolderDO {
    [...]
    private Set<UserPermission>  userPermissions;
    [...]
Java:
public class UserPermission {
   [...]
   private UserDO user;
   private AccessRight right;
   [...]

Das scheint mir aus Java-Sicht der bessere Aufbau zu sein.
Liege ich da richtig? Falls ja, ist mir allerdings nicht ganz klar, wie ich das dann persistieren soll.

Außerdem ist nach meinem Verständnis das AcessRight nicht Bestandteil der eindeutigen Id. Die wird bereits über die Kombination von User/Folder ausgedrückt.

Da hast du vollkommen Recht, danke für den Hinweis. 🙂
 
Das scheint mir aus Java-Sicht der bessere Aufbau zu sein.
Liege ich da richtig?
Ja, die neue Struktur scheint mir auch sinnvoller. So "kennt" ein Folder seine berechtigten Nutzer und das Recht. Das scheint mir logischer.
Falls ja, ist mir allerdings nicht ganz klar, wie ich das dann persistieren soll.
Mit Hibernate sollte Dich das nicht so belasten. Wenn du dem Set (in Java) weitere Elemente hinzufügst und dann das Folder-Objekt persistest, werden die richtigen INSERTS/UPDATES von Hibernate automatisch gemacht.
 
Zuletzt bearbeitet von einem Moderator:

Zurück
Oben