2017-06-09 4 views
0

Ich verwende Spring Data mit einer MongoDB, um einige Dokumente zu speichern. Beim Speichern von Dokumenten möchte ich, dass Mongo keine leeren Objekte enthält. (Wie) kann dies erreicht werden?Spring Data MongoDB - leere Objekte ignorieren

sagen, dass ich die folgende Hauptklasse haben:

@Document(collection = "main_doc") 
public class MainDoc { 
    @Id 
    private String id; 

    private String title; 
    private SubDoc subDoc; 
} 

, die ein Objekt der folgenden Klasse enthält:

public class SubDoc { 

    private String title; 
    private String info; 

} 

Nun, wenn ich das folgende Objekt zu speichern versuchen würde:

MainDoc main = new MainDoc(); 
main.setTitle("someTitle"); 
main.setSubDoc(new SubDoc()); 

Hinweis: in Wirklichkeit kontrolliere ich nicht die Tatsache, dass der SubDoc so eingestellt ist. Es kann entweder leer oder ausgefüllt sein. Was ich will ist, dass, wenn die Eigenschaften/Felder eines Elements alle NULL sind, es überhaupt nicht in Mongo gespeichert wird. Diese ergibt so etwas in Mongo:

{ 
    "_id" : "5a328f9a-6118-403b-a3a0-a55ce52099f3", 
    "title": "someTitle", 
    "subDoc": {} 
} 

Was Ich mag, ist, dass, wenn ein Element nur null Eigenschaften enthält, werden diese nicht gespeichert, so für das obige Beispiel ich folgendes Ergebnis möchte :

@NoRepositoryBean 
public interface MainRepo extends CrudRepository<MainDoc, String> { 

    // save inherited 

} 

Vielen Dank im Voraus:

{ 
    "_id" : "5a328f9a-6118-403b-a3a0-a55ce52099f3", 
    "title": "someTitle" 
} 

Speichern von Dokumenten mit Hilfe eines Endlagers wie folgt durchgeführt.

+1

Rufen Sie nicht 'main.setSubDoc (new SubDoc());' Sie setzen es auf leer. Wenn du das nicht nennst, wird es nicht da sein. –

+0

Ja, aber in meinem tatsächlichen Anwendungsfall kann ich diesen Teil nicht kontrollieren. Ich brauche es wirklich während des Mappings. Entschuldigung, hätte mir das deutlicher machen sollen. – CounterFlame

+0

Können Sie in Ihrer Frage dann genauer sein? Es scheint mir, dass, wenn es keine Daten gibt, die Sie dort eingeben, Sie einfach nicht anrufen. Vielleicht brauchst du ein "if" in deinem Code. –

Antwort

1

Eine Sache, die Sie hier tun können, ist Ihre benutzerdefinierte Konverter für MainDoc zu schreiben:

public class MainDocConverter implements Converter<MainDoc, DBObject> { 
    @Override 
    public DBObject convert(final MainDoc source) { 
     final BasicDbObject dbObject = new BasicDBObject(); 
     ... 
     if(/* validate is subdoc is not null and not empty */) { 
      dbOject.put("subDoc", source.getSubDoc()); 
     } 
    } 
} 

Sie es zum Beispiel in @Configuration Datei registrieren:

@Configuration 
@EnableMongoRepositories(basePackages = {"package"}) 
public class MongoConfig { 

    private final MongoDbFactory mongoDbFactory; 

    public MongoConfig(final MongoDbFactory mongoDbFactory) { 
     this.mongoDbFactory = mongoDbFactory; 
    } 

    @Bean 
    public MongoTemplate mongoTemplate() throws Exception { 

     final MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, getDefaultMongoConverter()); 
     return mongoTemplate; 

    } 

    @Bean 
    public MappingMongoConverter getDefaultMongoConverter() throws Exception { 

     final MappingMongoConverter converter = new MappingMongoConverter(
       new DefaultDbRefResolver(mongoDbFactory), new MongoMappingContext()); 
     converter.setCustomConversions(new CustomConversions(Arrays.asList(new MainDocConverter()))); 

     return converter; 
    } 

} 

Wenn Sie nicht wollen, Schreiben Sie einen benutzerdefinierten Konverter für Ihr Objekt Spielzeug kann Standard verwenden und und ein wenig ändern.

final Document document = (Document) getDefaultMongoConverter().convertToMongoType(mainDoc); 

if(/* validate is null or is empty */) { 
    document .remove("subDoc"); 
} 

mongoTemplate().save(document); 

Eigentlich ist es nicht der beste Weg. Als Jungs schrieb leeres Objekt sollte als {} gespeichert werden, aber Konverter kann Ihnen mit Ihrem Fall helfen.

+0

Das würde mir ja was ich will, aber es würde immer noch eine Menge Überprüfungen erfordern. Wäre es möglich, von diesem benutzerdefinierten Konverter zuerst die Standardimplementierung aufzurufen und dann zu überprüfen, ob das Datenbankobjekt keine Felder enthält und in diesem Fall null zurückgibt? – CounterFlame

+1

@CounterFlame Ich habe meine Antwort bearbeitet. Sie können den Standardkonverter dafür verwenden. –

Verwandte Themen