I want to strore Object to MongoDB with Morphia.
But I got bunch of exceptions:
Exception in thread "main" java.lang.IllegalArgumentException: can't serialize class com.aerlingus.ta.models.b2b.faresearch.AirSearchPrefsType$CabinPref
at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:270)
Here is this save():
public void create(MODEL model) {
Object keyValue = get(model);
if(datastore.find(this.model).field(keyField.id()).equal(keyValue).get() == null){
datastore.save(model);
} else {
throw new RuntimeException(String.format("Duplicate parameters '%s' : '%s'", keyField.id(), keyValue));
}
}
Here is AirSearchPrefsType class:
@Embedded
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
public static class CabinPref {
@Embedded @Compare
@XmlAttribute(name = "PreferLevel")
protected PreferLevelType preferLevel;
@Embedded @Compare
@XmlAttribute(name = "Cabin")
protected CabinType cabin;
@Transient
@XmlAttribute(name = "CabinSubtype")
protected String cabinSubtype;
and PreferLevelType:
@Embedded
@XmlType(name = "PreferLevelType")
@XmlEnum
public enum PreferLevelType {
@Embedded
@XmlEnumValue("Only")
ONLY("Only"),
@XmlEnumValue("Unacceptable")
@Embedded
UNACCEPTABLE("Unacceptable"),
@XmlEnumValue("Preferred")
@Embedded
PREFERRED("Preferred"),
@Embedded
@XmlEnumValue("Required")
REQUIRED("Required"),
@Embedded
@XmlEnumValue("NoPreference")
NO_PREFERENCE("NoPreference");
private final String value;
and CabinType:
@Embedded
@XmlType(name = "CabinType")
@XmlEnum
public enum CabinType {
@XmlEnumValue("First")
FIRST("First"),
@XmlEnumValue("Business")
BUSINESS("Business"),
@XmlEnumValue("Economy")
ECONOMY("Economy");
private final String value;
I couldn't understand what is wrong here. Does Morphia wiorks with static inner classes or with enums.
How to solve this trouble?
The following code will show exceptions like yours:
package com.test.mongodb;
import java.io.IOException;
import java.io.Serializable;
import org.junit.Test;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.MongoClient;
public class TestMongo {
static class Temp implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
public Temp(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
@Test
public void test() {
try {
MongoClient mongoClient = new MongoClient();
DBCollection collection = mongoClient.getDB("test").getCollection("temp");
Temp temp = new Temp("Current time: " + System.currentTimeMillis());
collection.insert(new BasicDBObject("JavaObject", temp));
} catch (IOException e) {
e.printStackTrace();
}
}
}
You can try this way:
package com.test.mongodb;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.junit.Test;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
public class TestMongo {
static class Temp implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
public Temp(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
@Test
public void test(){
try {
MongoClient mongoClient = new MongoClient();
DBCollection collection = mongoClient.getDB("test").getCollection("temp");
Temp temp = new Temp("Currect time: " + System.currentTimeMillis());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(temp);
collection.insert(new BasicDBObject("JavaObject", baos.toByteArray()));
readObject(collection);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* read the java object from mongodb
* @param collection
*/
public void readObject(DBCollection collection){
try {
DBCursor cursor = collection.find();
for (DBObject dbObject : cursor) {
ByteArrayInputStream bais = new ByteArrayInputStream((byte[]) dbObject.get("JavaObject"));
ObjectInputStream ois = new ObjectInputStream(bais);
Temp temp = (Temp) ois.readObject();
System.out.println(temp.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
This approach doesn't conform to Morphia exactly, but to Mongo itself.