Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add simple JsonNode mapping to postgres json db type example
- Loading branch information
Showing
5 changed files
with
265 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
x-postgres-features/src/main/java/org/example/domain/SimpleDoc.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package org.example.domain; | ||
|
||
import com.fasterxml.jackson.databind.JsonNode; | ||
|
||
import javax.persistence.Entity; | ||
import javax.persistence.Id; | ||
import javax.persistence.Table; | ||
import javax.persistence.Version; | ||
|
||
@Entity | ||
@Table(name="p_doc") | ||
public class SimpleDoc { | ||
|
||
@Id | ||
Long id; | ||
|
||
@Version | ||
Long version; | ||
|
||
String name; | ||
|
||
JsonNode content; | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public void setId(Long id) { | ||
this.id = id; | ||
} | ||
|
||
public Long getVersion() { | ||
return version; | ||
} | ||
|
||
public void setVersion(Long version) { | ||
this.version = version; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public void setName(String name) { | ||
this.name = name; | ||
} | ||
|
||
public JsonNode getContent() { | ||
return content; | ||
} | ||
|
||
public void setContent(JsonNode content) { | ||
this.content = content; | ||
} | ||
} |
91 changes: 91 additions & 0 deletions
91
x-postgres-features/src/main/java/org/example/domain/type/ScalarTypeJsonNodePostgres.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package org.example.domain.type; | ||
|
||
|
||
import com.avaje.ebeaninternal.server.type.DataBind; | ||
import com.avaje.ebeaninternal.server.type.ScalarTypeBaseVarchar; | ||
import com.fasterxml.jackson.core.JsonGenerator; | ||
import com.fasterxml.jackson.core.JsonParser; | ||
import com.fasterxml.jackson.core.JsonToken; | ||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import org.postgresql.util.PGobject; | ||
|
||
import java.io.IOException; | ||
import java.sql.SQLException; | ||
import java.sql.Types; | ||
|
||
public class ScalarTypeJsonNodePostgres extends ScalarTypeBaseVarchar<JsonNode> { | ||
|
||
public ScalarTypeJsonNodePostgres() { | ||
this(DBTYPE_JSON, new ObjectMapper()); | ||
} | ||
|
||
/** | ||
* Postgres DB type JSON. | ||
*/ | ||
private static final String DBTYPE_JSON = "json"; | ||
|
||
/** | ||
* Postgres DB type JSONB. | ||
*/ | ||
private static final String DBTYPE_JSONB = "jsonb"; | ||
|
||
final ObjectMapper objectMapper; | ||
|
||
final String dbType; | ||
|
||
protected ScalarTypeJsonNodePostgres(String dbType, ObjectMapper objectMapper) { | ||
super(JsonNode.class, false, Types.VARCHAR); | ||
this.objectMapper = objectMapper; | ||
this.dbType = dbType; | ||
} | ||
|
||
@Override | ||
public void bind(DataBind b, JsonNode value) throws SQLException { | ||
|
||
String rawJson = (value == null) ? null : formatValue(value); | ||
|
||
PGobject pgo = new PGobject(); | ||
pgo.setType(dbType); | ||
pgo.setValue(rawJson); | ||
b.setObject(pgo); | ||
} | ||
|
||
@Override | ||
public JsonNode jsonRead(JsonParser ctx, JsonToken event) throws IOException { | ||
|
||
return objectMapper.readValue(ctx, JsonNode.class); | ||
} | ||
|
||
@Override | ||
public void jsonWrite(JsonGenerator ctx, String name, JsonNode value) throws IOException { | ||
|
||
ctx.writeFieldName(name); | ||
objectMapper.writeTree(ctx, value); | ||
} | ||
|
||
@Override | ||
public String formatValue(JsonNode v) { | ||
return v.toString(); | ||
} | ||
|
||
@Override | ||
public JsonNode parse(String value) { | ||
|
||
try { | ||
return objectMapper.readTree(value); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
@Override | ||
public JsonNode convertFromDbString(String dbValue) { | ||
return parse(dbValue); | ||
} | ||
|
||
@Override | ||
public String convertToDbString(JsonNode beanValue) { | ||
return formatValue(beanValue); | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
x-postgres-features/src/test/java/org/example/SimpleDocTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package org.example; | ||
|
||
import com.avaje.ebean.Ebean; | ||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import org.example.domain.SimpleDoc; | ||
import org.junit.Test; | ||
|
||
import java.io.IOException; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertNull; | ||
|
||
public class SimpleDocTest extends ExampleBaseTestCase { | ||
|
||
@Test | ||
public void test() throws IOException { | ||
|
||
ObjectMapper mapper = new ObjectMapper(); | ||
|
||
String rawJson = "{\"docName\":\"rob doc\", \"docScore\":234}"; | ||
|
||
JsonNode jsonNode = mapper.readTree(rawJson); | ||
|
||
SimpleDoc doc = new SimpleDoc(); | ||
doc.setName("doc1"); | ||
doc.setContent(jsonNode); | ||
|
||
Ebean.save(doc); | ||
|
||
|
||
String fullJson = Ebean.json().toJson(doc); | ||
|
||
SimpleDoc doc2 = Ebean.json().toBean(SimpleDoc.class, fullJson); | ||
|
||
assertEquals(doc.getId(), doc2.getId()); | ||
assertEquals(doc.getName(), doc2.getName()); | ||
assertEquals(doc.getVersion(), doc2.getVersion()); | ||
assertEquals(doc.getContent().toString(), doc2.getContent().toString()); | ||
|
||
SimpleDoc doc3 = Ebean.find(SimpleDoc.class, doc.getId()); | ||
assertEquals(doc.getId(), doc3.getId()); | ||
assertEquals(doc.getName(), doc3.getName()); | ||
assertEquals(doc.getVersion(), doc3.getVersion()); | ||
assertEquals(doc.getContent().toString(), doc3.getContent().toString()); | ||
|
||
} | ||
|
||
@Test | ||
public void testNullValue() throws IOException { | ||
|
||
|
||
SimpleDoc doc = new SimpleDoc(); | ||
doc.setName("doc1"); | ||
|
||
Ebean.save(doc); | ||
|
||
|
||
String fullJson = Ebean.json().toJson(doc); | ||
|
||
SimpleDoc doc2 = Ebean.json().toBean(SimpleDoc.class, fullJson); | ||
|
||
assertEquals(doc.getId(), doc2.getId()); | ||
assertEquals(doc.getName(), doc2.getName()); | ||
assertEquals(doc.getVersion(), doc2.getVersion()); | ||
assertNull(doc2.getContent()); | ||
|
||
|
||
SimpleDoc doc3 = Ebean.find(SimpleDoc.class, doc.getId()); | ||
assertEquals(doc.getId(), doc3.getId()); | ||
assertEquals(doc.getName(), doc3.getName()); | ||
assertEquals(doc.getVersion(), doc3.getVersion()); | ||
assertNull(doc3.getContent()); | ||
|
||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
x-postgres-features/src/test/java/org/example/domain/type/ScalarTypeJsonNodeTextTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package org.example.domain.type; | ||
|
||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import org.junit.Test; | ||
|
||
import java.sql.Types; | ||
|
||
import static org.junit.Assert.*; | ||
|
||
/** | ||
* | ||
*/ | ||
public class ScalarTypeJsonNodeTextTest { | ||
|
||
ScalarTypeJsonNodePostgres type = new ScalarTypeJsonNodePostgres();//.JSON(new ObjectMapper()); | ||
|
||
@Test | ||
public void testParse() throws Exception { | ||
|
||
String jsonInput = "{\"id\":123123, \"name\":\"foo\"}"; | ||
|
||
JsonNode node = type.parse(jsonInput); | ||
assertEquals(123123L, node.get("id").asLong()); | ||
assertEquals("foo", node.get("name").asText()); | ||
|
||
node = type.convertFromDbString(jsonInput); | ||
assertEquals(123123L, node.get("id").asLong()); | ||
assertEquals("foo", node.get("name").asText()); | ||
|
||
String rawJson = type.formatValue(node); | ||
|
||
assertTrue(rawJson, rawJson.contains("\"id\":123123")); | ||
assertTrue(rawJson, rawJson.contains("\"name\":\"foo\"")); | ||
|
||
rawJson = type.convertToDbString(node); | ||
assertTrue(rawJson, rawJson.contains("\"id\":123123")); | ||
assertTrue(rawJson, rawJson.contains("\"name\":\"foo\"")); | ||
|
||
} | ||
|
||
} |