PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : JPA, EclipseLink 2.0 dynamisches Mapping


Tiamat
2010-05-17, 16:53:03
Hi,
ich hab da ein kleines Problem. Mit dem ORM-Framework EclipseLink sollen Schemabescheibung für Tabellen, sowie Tabellen selbst dynamisch erzeugt werden. Wenn der Teil erstmal funktioniert, soll der User sich dann anschließend sogar ganze Schemen zurecht klicken können.
Ich hab mich ein wenig durch das wiki und die API gewühlt, ein paar Beispiele ausprobiert und zwei davon in die engere Auswahl genommen. Leider hakt es bei beiden. Um meinen anderen statischen Schemateil nicht zu gefährden, hab ich die dynamischen Entitäten in ne eigene Persistence Unit verschoben.

Kennt sich da vielleicht zufällig jemand super aus? Leider sind nahezu sämtliche Beispiel fehlerbehaftet und aus der API selbst entnehme ich keine hilfreiche Information.

Gruß
Tiamat

ThePsycho
2010-05-17, 18:57:51
Ich kenne mich nicht super aus, beschäftige mich damit aber z.Z. beruflich. Muss da aber auch erst mal reinkommen.
Evtl. kann ich weiterhelfen, dann brauche ich aber konkretere Infos.

Tiamat
2010-05-18, 08:49:25
Hi, ja klar.

Ich hab wie gesagt ein paar Beispiel untersucht, zwei gefunden, bei denen wenigstens ne Tabelle erzeugt wurde, auch wenn ich gleich mit ner Exception konfrontiert wurde. Da mir nicht klar ist, wo die Exception auftritt oder warum sie auftrifft, hab ich soweit Code auskommentiert, bis ich zum eigentlichen Fehler komme. Den Part färbe ich mal mit rot. Wenn ich den Code so ablaufen lasse, wird die erste Tabelle blue angelegt, wirft darauf hin ne Exception mit der Meldung "Die Tabelle sei schon da". Anhand des Codes kann ich keine Fehler oder Unzulänglichkeiten erkennen.

Besten Dank schon mal.

Gruß
Tiamat


public static EntityManagerFactory getEmf() {

HashMap<String, String> connectionProperties;
connectionProperties = new HashMap<String, String>();
connectionProperties.put("eclipselink.jdbc.password", "pass");
connectionProperties.put("eclipselink.jdbc.user", "username");
connectionProperties.put("eclipselink.jdbc.driver", "com.mysql.jdbc.Driver");
connectionProperties.put("eclipselink.jdbc.url", "jdbc:mysql://localhost:3306/db");
EntityManagerFactory emf = Persistence.createEntityManagerFactory("UPS", connectionProperties);
return emf;

}

public void createTestEntities() {
EntityManagerFactory emf = getEMF();
EntityManager em = emf.createEntityManager();


try {
// der Dynamic Class Loader benötigt eine Session
Session session = JpaHelper.getEntityManager(em).getServerSession();
DynamicClassLoader dcl = DynamicClassLoader.lookup(session);

// Name der Tabellen
String tableName = "BLUE";
String objectName = tableName;

String tableName2 = "GREEN";
String objectName2 = tableName2;

// Die eigentlichen dynamischen Klassen
Class<?> clazz = dcl.createDynamicClass("com.example." + objectName);
Class<?> clazz2 = dcl.createDynamicClass("com.example2" + objectName2);

DynamicTypeBuilder builder = null;
DynamicTypeBuilder builder2 = null;


builder = new JPADynamicTypeBuilder(clazz, null, tableName);
// Die Attribute werden im Key-Value-Style gesetzt
builder.addDirectMapping("ID", Long.class, "MyID");
builder.addDirectMapping("STRING", String.class, "name");
builder.setPrimaryKeyFields("MyID");

builder2 = new JPADynamicTypeBuilder(clazz2, null, tableName2);
builder2.addDirectMapping("ID", Long.class, "YourID");
builder2.addDirectMapping("STRING", String.class, "name");
builder2.setPrimaryKeyFields("YourID");



DynamicType type = builder.getType();
DynamicHelper dynamicHelper = new JPADynamicHelper(em);
dynamicHelper.addTypes(true /* create table */, false /*foreign key constraints*/, type);


DynamicType type2 = builder.getType();
DynamicHelper dynamicHelper2 = new JPADynamicHelper(em);
dynamicHelper2.addTypes(true /* create table */, false /*foreign key contraints */, type2);
catch(DynamicException e) {

} catch(PersistenceException e) {

} catch(Exception e) {

}

Frucht-Tiger
2010-05-18, 10:51:54
Poste auch noch mal bitte die Exception, hab ich es richtig verstanden das es mit nur einer Tabelle fehlerfrei geht?

Tiamat
2010-05-19, 07:27:07
Moin,

also zu Beginn war es so, dass die statischen Entitäten und die dynamischen Entitäten in der selben Persistence-Unit lagen. Da wurde das Erzeugen einer dynamischen Entität dadurch verhindert, dass ich seltsame Fehlermeldungen bekam, die lustigerweise nichts mit den dynamischen Entitäten zu tun hatte, sondern mit Entitäten die statisch deklariert wurden.

Also Verschiebung in eine andere Persistence-Unit.

@Frucht-Tiger: Es ist eine Mysql-Syntax Exception: dbx.blue already exist.
Die Exception kommt immer, die Tabelle wurde beim Nachsehen aber erzeugen.
Dbx ist in dem Fall die Datenbank.
Vor jedem Durchlauf hab ich die Datenbank jeweils gedropped und wieder erzeugt. Mein Eindruck von der Geschichte ist, dass dieses Feature noch ziemlich buggy ist. Es ist auch kein Feature, dass in der Persistence API definiert wurde, sondern wird durch explizites Importieren von "org.eclipse.persistence.dynamic u.s.w" ermöglicht.

Frucht-Tiger
2010-05-19, 10:40:19
Ich hab von dir auch das erste mal von dem Feature gehört, bei Sachen ausserhalb der JPA spec kenn ich mich eher in Richtung Hibernate aus. Was passiert eigentlich wenn du die ddl-generation* auf drop-create stellst? Hat das überhaupt einen Einfluss auf die dynamischen Tabellen?

So richtig weiterhelfen können dir bei dem Problem aber wahrscheinlich nur die Entwickler auf der Mailing-Liste, ich denke nicht das die Sache so buggy läuft, sonder einfach die API nicht so benutzt wird wie die sich das vorstellen.


*connectionProperties.put("eclipselink.ddl-generation", "drop-and-create-tables");

ThePsycho
2010-05-19, 20:31:43
Hmm da muss ich leider auch passen. Sind diese Methoden denn irgendwie dokumentiert?
JPA-Mechanismen sind das ja nicht.

Tiamat
2010-05-20, 07:29:25
Da er ne über die Connection Properties ne Verbindung zur Datenbank aufbaut, denk ich, dass drop-create auch funktioniert.
Naja ich versuch mal jemand bei EclipseLink zu kontaktieren.
Trotzdem danke