Code:
ich hoffe ihr könnt mir bei meinem Problem helfen:
Ich bin dabei eine Anwendung in Java zu schreiben. Sie soll REST Services als Schnittstellen anbieten und läuft daher mit Jersey in Tomcat. Zum Speichern der Objekte dachte ich an DB4O (oder gibt es eine andere einfache Möglichkeit?). Daher habe ich DB4O als separates Projekt in Eclipse als Java Anwendung angelegt und betreibe die DB im Client/Server Modus. Zum testen habe ich eine Java SE Anwendung geschrieben...das klappt auch.
Wenn ich nun die selbe Klasse in den Tomcat schiebe und Aufrufe kommt es sehr häufig zu Exceptions. Sehr selten gelingt ein "store" oder ein "query" und das ohne! etwas am Code zu ändern.
Der Fehler:
Code:
Jan 14, 2013 10:59:01 AM com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException
SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
java.lang.ClassCastException: entities.MeineKlasse cannot be cast to com.db4o.reflect.generic.GenericObject
at com.db4o.reflect.generic.GenericField.get(GenericField.java:36)
at com.db4o.internal.reflect.StrictFieldAccessor.get(StrictFieldAccessor.java:13)
at com.db4o.internal.FieldMetadata.getOrCreate(FieldMetadata.java:555)
...
Code:
import com.db4o.*;
import com.db4o.cs.*;
import com.db4o.cs.config.*;
import com.db4o.messaging.*;
/**
* starts a db4o server with the settings from {@link ServerInfo}.
<br>
* <br>
* This is a typical setup for a long running server. <br>
* <br>
* The Server may be stopped from a remote location by running
StopServer. The
* StartServer instance is used as a MessageRecipient and reacts to
receiving an
* instance of a StopServer object. <br>
* <br>
*/
public class StartServer implements ServerInfo, MessageRecipient {
/**
* setting the value to true denotes that the server should be
closed
*/
private boolean stop = false;
/**
* starts a db4o server using the configuration from {@link
ServerInfo}.
*/
public static void main(String[] arguments) {
new StartServer().runServer();
}
/*** opens the ObjectServer, and waits forever until close() is
called or a
* StopServer message is being received.
*/
public void runServer() {
synchronized (this) {
ServerConfiguration config =
Db4oClientServer.newServerConfiguration();
// Using the messaging functionality to redirect all
// messages to this.processMessage
config.networking().messageRecipient(this);
//config.file().lockDatabaseFile(false);
ObjectServer db4oServer =
Db4oClientServer.openServer(config
, FILE, PORT);
db4oServer.grantAccess(USER, PASS);
// to identify the thread in a debugger
Thread.currentThread().setName(this.getClass().getName());
// We only need low priority since the db4o server has
// it's own thread.
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
try {
if (!stop) {
// wait forever for notify() from close()
this.wait(Long.MAX_VALUE);
}
} catch (Exception e) {
e.printStackTrace();
}
db4oServer.close();
}
}
/**
* messaging callback
*
* @see
com.db4o.messaging.MessageRecipient#processMessage(MessageContext,
* Object)
*/public void processMessage(MessageContext con, Object message) {
if (message instanceof StopServer) {
close();
}
}
/**
* closes this server.
*/
public void close() {
synchronized (this) {
stop = true;
this.notify();
}
}
}
Die Klasse für den Datenbankzugriff:
Code:
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.cs.Db4oClientServer;
public class Database {
private ObjectContainer container = null;
public ObjectSet<Object> queryObject(Object obj){
ObjectSet<Object> result = getDatabase().queryByExample(obj);
return result;
}
public void storeObject(Object o){
getDatabase().store(o);
}
private ObjectContainer getDatabase(){
if(container==null)
container = Db4oClientServer.openClient("localhost", 50000, "test", "test);
return container;
}
public void closeDatabase(){
if(container !=null){
container.close();
container = null;
}
}
}
Und das REST Interface:
Code:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import database.*;
import entities.MeineKlasse;
@Path("/service")
public class Service{
@POST
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String Service(@FormParam("id") String id){
Database data = new Database();
//Eventuell vorhandes Objekt suchen und updaten
MeineKlasse dummy = new MeineKlasse(id);
ObjectSet<Object> obj = data.queryObject(dummy);
MeineKlasse klasse;
for(int i=0;i<obj.size();i++){
klasse= (MeineKlasse)obj.get(i);
if(klasse.getId().equals(id)){
klasse.setId(id);
}
}
klasse= dummy;
klasse.setId(id);
data.storeObject(klasse);
//Abfrage, ob Objekt gespeichert wurde
ObjectSet<Object> objs = data.queryObject(new MeineKlasse());
MeineKlasse s;
for (int i=0;i<objs.size();i++){
s=(MeineKlasse)objs.get(i);
System.out.println("...");
}
return id;
}
}
Was mache ich falsch? Oder gibt es eine andere einfache Möglichkeit der Speicherung?
Vielen Dank schonmal für eure Hilfe
Viele Grüße,
DarkAngelfire