Skip to content

Commit

Permalink
Add simple JsonNode mapping to postgres json db type example
Browse files Browse the repository at this point in the history
  • Loading branch information
rbygrave committed May 11, 2015
1 parent 3ad711e commit 45d7e67
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 1 deletion.
Expand Up @@ -19,7 +19,7 @@ public class Customer extends BaseModel {
/**
* Convenience Finder for 'active record' style.
*/
public static final Finder<Long,Customer> find = new Finder<>(Long.class, Customer.class);
public static final Finder<Long,Customer> find = new Finder<>(Customer.class);

boolean inactive;

Expand Down
@@ -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;
}
}
@@ -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 x-postgres-features/src/test/java/org/example/SimpleDocTest.java
@@ -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());

}
}
@@ -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\""));

}

}

0 comments on commit 45d7e67

Please sign in to comment.