简体   繁体   中英

Morphia can't insert class into DB

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM