我想用Morphia将对象引用到MongoDB。
但我有很多例外:
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)
以下是 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));
}
}
以下是 AirSearchPrefsType类 :
@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;
和 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;
和 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;
我无法理解这里有什么问题。 Morphia是否会使用静态内部类或枚举。
如何解决这个问题?
答案 0 :(得分:1)
以下代码将显示与您类似的例外情况:
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();
}
}
}
您可以尝试这种方式:
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();
}
}
}
这种方法并不完全符合Morphia,而是符合Mongo本身。