{"id":4651,"date":"2018-03-25T08:53:15","date_gmt":"2018-03-25T12:53:15","guid":{"rendered":"http:\/\/kodegeek.com\/blog\/?p=4651"},"modified":"2018-03-30T10:14:49","modified_gmt":"2018-03-30T14:14:49","slug":"serializando-objetos-en-java-pojo-usando-codecs-i","status":"publish","type":"post","link":"http:\/\/kodegeek.com\/blog\/2018\/03\/25\/serializando-objetos-en-java-pojo-usando-codecs-i\/","title":{"rendered":"Serializando objetos en MONGODB Java (POJO) usando Codecs (I)"},"content":{"rendered":"<p>Estos d\u00edas he estado trabajando con Java JPA para un proyecto de la oficina; Tambi\u00e9n he estado trabajando con MongoDB y objetos con soporte para JAXP para CVEBrowser.<\/p>\n<p>No es tan f\u00e1cil como parece :-). En el caso de Mongo no tiene sentido pensar en JPA (aunque hay soporte para esto), as\u00ed que comenc\u00e9 a jugar con el API del manejado de conexiones.<\/p>\n<p>La raz\u00f3n es que cuando tenemos un esquema previo, por ejemplo una definici\u00f3n que viene de XSD, no hay mucha elecci\u00f3n en cuanto a como se ven los atributos.<\/p>\n<p>Veamos por ejemplo una clase que resulta de convertir la definici\u00f3n de una entrada de <a href=\"https:\/\/cve.mitre.org\/schema\/cve\/cve_1.0.xsd\" rel=\"noopener\" target=\"_blank\">XSD CVE (https:\/\/cve.mitre.org\/schema\/cve\/cve_1.0.xsd)<\/a>.<\/p>\n<pre lang=\"Java\">\r\n\/\/\r\n\/\/ This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 \r\n\/\/ See <a href=\"http:\/\/java.sun.com\/xml\/jaxb\">http:\/\/java.sun.com\/xml\/jaxb<\/a> \r\n\/\/ Any modifications to this file will be lost upon recompilation of the source schema. \r\n\/\/ Generated on: 2018.02.17 at 08:52:30 PM EST \r\n\/\/\r\n\r\n\r\npackage com.kodegeek.cvebrowser.entity;\r\n\r\nimport javax.xml.bind.annotation.XmlEnum;\r\nimport javax.xml.bind.annotation.XmlEnumValue;\r\nimport javax.xml.bind.annotation.XmlType;\r\n\r\n\r\n\/**\r\n * Java class for simplePhaseEnumType.\r\n * \r\n * The following schema fragment specifies the expected content contained within this class.\r\n * \r\n * \r\n * &lt;simpleType name=\"simplePhaseEnumType\">\r\n *   &lt;restriction base=\"{http:\/\/www.w3.org\/2001\/XMLSchema}token\">\r\n *     &lt;enumeration value=\"Proposed\"\/>\r\n *     &lt;enumeration value=\"Interim\"\/>\r\n *     &lt;enumeration value=\"Modified\"\/>\r\n *     &lt;enumeration value=\"Assigned\"\/>\r\n *   &lt;\/restriction>\r\n * &lt;\/simpleType>\r\n * \r\n * \r\n *\/\r\n@XmlType(name = \"simplePhaseEnumType\")\r\n@XmlEnum\r\npublic enum SimplePhaseEnumType {\r\n\r\n    @XmlEnumValue(\"Proposed\")\r\n    PROPOSED(\"Proposed\"),\r\n    @XmlEnumValue(\"Interim\")\r\n    INTERIM(\"Interim\"),\r\n    @XmlEnumValue(\"Modified\")\r\n    MODIFIED(\"Modified\"),\r\n    @XmlEnumValue(\"Assigned\")\r\n    ASSIGNED(\"Assigned\");\r\n    private final String value;\r\n\r\n    SimplePhaseEnumType(String v) {\r\n        value = v;\r\n    }\r\n\r\n    public String value() {\r\n        return value;\r\n    }\r\n\r\n    public static SimplePhaseEnumType fromValue(String v) {\r\n        for (SimplePhaseEnumType c: SimplePhaseEnumType.values()) {\r\n            if (c.value.equals(v)) {\r\n                return c;\r\n            }\r\n        }\r\n        throw new IllegalArgumentException(v);\r\n    }\r\n\r\n}\r\n<\/pre>\n<p>Ahora mi problema es que puedo guardar los datos (aparentemente) pero no puedo recuperarlos debido a que el codec no puede transformar la enumeraci\u00f3n (la cual por definici\u00f3n no tiene constructores p\u00fablicos). <\/p>\n<p>Seg\u00fan MongoDB (<a href=\"https:\/\/github.com\/mongodb\/mongo-java-driver\/blob\/master\/driver-async\/src\/examples\/tour\/PojoQuickTour.java\" rel=\"noopener\" target=\"_blank\">PojoQuickTour,java<\/a>), deber\u00eda ser tan f\u00e1cil como usar una base de datos con el Codec apropiado:<\/p>\n<pre lang=\"Java\">\r\n\r\nprivate final static String [] packages = {  \"com.kodegeek.cvebrowser.entity\" };\r\n\/\/ ...\r\n\r\npublic static CodecRegistry getCodecRegistry() {\r\n        final CodecRegistry defaultCodecRegistry = MongoClient.getDefaultCodecRegistry();\r\n        final CodecProvider pojoCodecProvider = PojoCodecProvider.builder().register(packages).build();\r\n        final CodecRegistry cvePojoCodecRegistry = CodecRegistries.fromProviders(pojoCodecProvider);\r\n        return CodecRegistries.fromRegistries(defaultCodecRegistry, cvePojoCodecRegistry);\r\n    }\r\n\r\n\/\/ Later on, different place we get a database with a POJO codec\r\n\/\/ ...\r\nmongoClient.getDatabase(\"cvebrowser\").withCodecRegistry(getCodecRegistry())\r\n\r\n\r\n<\/pre>\n<p>Sin embargo si trato de hacer una b\u00fasqueda usando el codec (Joses-iMac:CVEBrowser josevnz$ gradle test):<\/p>\n<pre lang=\"Java\">\r\norg.bson.codecs.configuration.CodecConfigurationException: Failed to decode 'phase'. Failed to decode 'value'. Cannot find a public constructor for 'SimplePhaseEnumType'.\r\n\tat org.bson.codecs.pojo.PojoCodecImpl.decodePropertyModel(PojoCodecImpl.java:192)\r\n\tat org.bson.codecs.pojo.PojoCodecImpl.decodeProperties(PojoCodecImpl.java:168)\r\n\tat org.bson.codecs.pojo.PojoCodecImpl.decode(PojoCodecImpl.java:122)\r\n\tat org.bson.codecs.pojo.PojoCodecImpl.decode(PojoCodecImpl.java:126)\r\n\tat com.mongodb.operation.CommandResultArrayCodec.decode(CommandResultArrayCodec.java:52)\r\n\tat com.mongodb.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:60)\r\n\tat org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:84)\r\n\tat org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:41)\r\n\tat org.bson.codecs.configuration.LazyCodec.decode(LazyCodec.java:47)\r\n\tat org.bson.codecs.BsonDocumentCodec.readValue(BsonDocumentCodec.java:101)\r\n\tat com.mongodb.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:63)\r\n\tat org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:84)\r\n\tat org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:41)\r\n\tat com.mongodb.connection.ReplyMessage.<init>(ReplyMessage.java:51)\r\n\tat com.mongodb.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:301)\r\n\tat com.mongodb.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:255)\r\n\tat com.mongodb.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:98)\r\n\tat com.mongodb.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:441)\r\n\tat com.mongodb.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:80)\r\n\tat com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:189)\r\n\tat com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:264)\r\n\tat com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:126)\r\n\tat com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:118)\r\n\tat com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:226)\r\n\tat com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:217)\r\n\tat com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:120)\r\n\tat com.mongodb.operation.FindOperation$1.call(FindOperation.java:717)\r\n\tat com.mongodb.operation.FindOperation$1.call(FindOperation.java:711)\r\n\tat com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:471)\r\n\tat com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:415)\r\n\tat com.mongodb.operation.FindOperation.execute(FindOperation.java:711)\r\n\tat com.mongodb.operation.FindOperation.execute(FindOperation.java:83)\r\n\tat com.mongodb.Mongo$3.execute(Mongo.java:826)\r\n\tat com.mongodb.MongoIterableImpl.execute(MongoIterableImpl.java:130)\r\n\tat com.mongodb.MongoIterableImpl.iterator(MongoIterableImpl.java:77)\r\n\tat com.mongodb.MongoIterableImpl.forEach(MongoIterableImpl.java:100)\r\n\tat com.kodegeek.cvebrowser.persistence.TestCVEMongoPojoManager.testPrintIssues(TestCVEMongoPojoManager.java:47)\r\n<\/init><\/pre>\n<p>&#8220;Failed to decode &#8216;phase&#8217;. Failed to decode &#8216;value&#8217;. Cannot find a public constructor for &#8216;SimplePhaseEnumType&#8221;. Estoy aprendiendo como ense\u00f1arle a MongoDB como guardar y leer estos valores sin que le de un infarto.<\/p>\n<p>(Por cierto, <a href=\"https:\/\/stackoverflow.com\/questions\/49477589\/cannot-read-or-serialize-pojo-with-enumerations-using-java-mongodb-driver\" rel=\"noopener\" target=\"_blank\">estoy preguntando en StackOverFlow<\/a>. Vamos a ver que tan complicado es).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Estos d\u00edas he estado trabajando con Java JPA para un proyecto de la oficina; Tambi\u00e9n he estado trabajando con MongoDB y objetos con soporte para JAXP para CVEBrowser. No es tan f\u00e1cil como parece :-). En el caso de Mongo no tiene sentido pensar en JPA (aunque hay soporte para esto), as\u00ed que comenc\u00e9 a <a class=\"read-more\" href=\"http:\/\/kodegeek.com\/blog\/2018\/03\/25\/serializando-objetos-en-java-pojo-usando-codecs-i\/\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[9,194,438],"tags":[],"_links":{"self":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/4651"}],"collection":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/comments?post=4651"}],"version-history":[{"count":8,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/4651\/revisions"}],"predecessor-version":[{"id":4659,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/4651\/revisions\/4659"}],"wp:attachment":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/media?parent=4651"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/categories?post=4651"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/tags?post=4651"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}