mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-13 06:42:57 +00:00
#2148 - PersistenceException: No ScalarType registered for class java.util.LinkedHashMap
This commit is contained in:
1 parent
449e0832e0
commit
5eac31283d
4 files changed
+96
-46
No files matched your search
@@ -3,6 +3,9 @@ package io.ebeaninternal.server.querydefn;
|
|||||||
import io.ebean.ExpressionList;
|
import io.ebean.ExpressionList;
|
||||||
import io.ebean.ProfileLocation;
|
import io.ebean.ProfileLocation;
|
||||||
import io.ebean.UpdateQuery;
|
import io.ebean.UpdateQuery;
|
||||||
|
import io.ebean.core.type.ScalarType;
|
||||||
|
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||||
|
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of UpdateQuery.
|
* Default implementation of UpdateQuery.
|
||||||
@@ -10,23 +13,30 @@ import io.ebean.UpdateQuery;
|
|||||||
public class DefaultUpdateQuery<T> implements UpdateQuery<T> {
|
public class DefaultUpdateQuery<T> implements UpdateQuery<T> {
|
||||||
|
|
||||||
private final OrmUpdateProperties values = new OrmUpdateProperties();
|
private final OrmUpdateProperties values = new OrmUpdateProperties();
|
||||||
|
|
||||||
private final DefaultOrmQuery<T> query;
|
private final DefaultOrmQuery<T> query;
|
||||||
|
private final BeanDescriptor<T> descriptor;
|
||||||
|
|
||||||
public DefaultUpdateQuery(DefaultOrmQuery<T> query) {
|
public DefaultUpdateQuery(DefaultOrmQuery<T> query) {
|
||||||
this.query = query;
|
this.query = query;
|
||||||
|
this.descriptor = query.getBeanDescriptor();
|
||||||
query.setUpdateProperties(values);
|
query.setUpdateProperties(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UpdateQuery<T> set(String property, Object value) {
|
public UpdateQuery<T> set(String property, Object value) {
|
||||||
values.set(property, value);
|
if (value == null) {
|
||||||
|
values.setNull(property);
|
||||||
|
} else {
|
||||||
|
final BeanProperty beanProperty = descriptor.getBeanProperty(property);
|
||||||
|
final ScalarType<Object> scalarType = (beanProperty == null) ? null: beanProperty.getScalarType();
|
||||||
|
values.set(property, value, scalarType);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UpdateQuery<T> setNull(String property) {
|
public UpdateQuery<T> setNull(String property) {
|
||||||
values.set(property, null);
|
values.setNull(property);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-11
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.querydefn;
|
package io.ebeaninternal.server.querydefn;
|
||||||
|
|
||||||
|
import io.ebean.core.type.ScalarType;
|
||||||
import io.ebeaninternal.server.deploy.DeployParser;
|
import io.ebeaninternal.server.deploy.DeployParser;
|
||||||
import io.ebeaninternal.server.persist.Binder;
|
import io.ebeaninternal.server.persist.Binder;
|
||||||
import io.ebeaninternal.server.type.DataBind;
|
import io.ebeaninternal.server.type.DataBind;
|
||||||
@@ -53,9 +54,11 @@ public class OrmUpdateProperties {
|
|||||||
private static class SimpleValue extends Value {
|
private static class SimpleValue extends Value {
|
||||||
|
|
||||||
final Object value;
|
final Object value;
|
||||||
|
final ScalarType<Object> scalarType;
|
||||||
|
|
||||||
SimpleValue(Object value) {
|
SimpleValue(Object value, ScalarType<Object> scalarType) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
this.scalarType = scalarType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -70,7 +73,11 @@ public class OrmUpdateProperties {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bind(Binder binder, DataBind dataBind) throws SQLException {
|
public void bind(Binder binder, DataBind dataBind) throws SQLException {
|
||||||
binder.bindObject(dataBind, value);
|
if (scalarType != null) {
|
||||||
|
scalarType.bind(dataBind, value);
|
||||||
|
} else {
|
||||||
|
binder.bindObject(dataBind, value);
|
||||||
|
}
|
||||||
dataBind.append(value).append(",");
|
dataBind.append(value).append(",");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,16 +122,12 @@ public class OrmUpdateProperties {
|
|||||||
*/
|
*/
|
||||||
private final LinkedHashMap<String, Value> values = new LinkedHashMap<>();
|
private final LinkedHashMap<String, Value> values = new LinkedHashMap<>();
|
||||||
|
|
||||||
/**
|
public void set(String propertyName, Object value, ScalarType<Object> scalarType) {
|
||||||
* Normal set property.
|
values.put(propertyName, new SimpleValue(value, scalarType));
|
||||||
*/
|
}
|
||||||
public void set(String propertyName, Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
values.put(propertyName, NULL_VALUE);
|
|
||||||
|
|
||||||
} else {
|
public void setNull(String propertyName) {
|
||||||
values.put(propertyName, new SimpleValue(value));
|
values.put(propertyName, NULL_VALUE);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.tests.json;
|
package org.tests.json;
|
||||||
|
|
||||||
import io.ebean.BaseTestCase;
|
import io.ebean.BaseTestCase;
|
||||||
import io.ebean.Ebean;
|
import io.ebean.DB;
|
||||||
import io.ebean.annotation.ForPlatform;
|
import io.ebean.annotation.ForPlatform;
|
||||||
import io.ebean.annotation.Platform;
|
import io.ebean.annotation.Platform;
|
||||||
import io.ebean.text.TextException;
|
import io.ebean.text.TextException;
|
||||||
@@ -25,7 +25,7 @@ import static org.junit.Assert.assertTrue;
|
|||||||
|
|
||||||
public class TestDbJson_List extends BaseTestCase {
|
public class TestDbJson_List extends BaseTestCase {
|
||||||
|
|
||||||
private EBasicJsonList bean = new EBasicJsonList();
|
private final EBasicJsonList bean = new EBasicJsonList();
|
||||||
|
|
||||||
private EBasicJsonList found;
|
private EBasicJsonList found;
|
||||||
|
|
||||||
@@ -57,9 +57,9 @@ public class TestDbJson_List extends BaseTestCase {
|
|||||||
bean.getBeanMap().put("key0", new PlainBean("k0", 90));
|
bean.getBeanMap().put("key0", new PlainBean("k0", 90));
|
||||||
bean.getBeanMap().put("key1", new PlainBean("k1", 91));
|
bean.getBeanMap().put("key1", new PlainBean("k1", 91));
|
||||||
|
|
||||||
Ebean.save(bean);
|
DB.save(bean);
|
||||||
|
|
||||||
found = Ebean.find(EBasicJsonList.class, bean.getId());
|
found = DB.find(EBasicJsonList.class, bean.getId());
|
||||||
|
|
||||||
assertThat(found.getTags()).containsExactly("one", "two");
|
assertThat(found.getTags()).containsExactly("one", "two");
|
||||||
assertTrue(found.getFlags().contains(42L));
|
assertTrue(found.getFlags().contains(42L));
|
||||||
@@ -81,7 +81,7 @@ public class TestDbJson_List extends BaseTestCase {
|
|||||||
//@Test//(dependsOnMethods = "insert")
|
//@Test//(dependsOnMethods = "insert")
|
||||||
public void json_parse_format() {
|
public void json_parse_format() {
|
||||||
|
|
||||||
String asJson = Ebean.json().toJson(found);
|
String asJson = DB.json().toJson(found);
|
||||||
assertThat(asJson).contains("\"tags\":[\"one\",\"two\"]");
|
assertThat(asJson).contains("\"tags\":[\"one\",\"two\"]");
|
||||||
assertThat(asJson).contains("\"flags\":[42,43,44]");
|
assertThat(asJson).contains("\"flags\":[42,43,44]");
|
||||||
assertThat(asJson).contains("\"plainBean\":{\"name\":\"plain\"");
|
assertThat(asJson).contains("\"plainBean\":{\"name\":\"plain\"");
|
||||||
@@ -90,7 +90,7 @@ public class TestDbJson_List extends BaseTestCase {
|
|||||||
assertThat(asJson).contains("\"beanMap\":{");
|
assertThat(asJson).contains("\"beanMap\":{");
|
||||||
assertThat(asJson).contains("\"id\":");
|
assertThat(asJson).contains("\"id\":");
|
||||||
|
|
||||||
EBasicJsonList fromJson = Ebean.json().toBean(EBasicJsonList.class, asJson);
|
EBasicJsonList fromJson = DB.json().toBean(EBasicJsonList.class, asJson);
|
||||||
assertEquals(found.getId(), fromJson.getId());
|
assertEquals(found.getId(), fromJson.getId());
|
||||||
assertEquals(found.getId(), fromJson.getId());
|
assertEquals(found.getId(), fromJson.getId());
|
||||||
assertEquals(found.getName(), fromJson.getName());
|
assertEquals(found.getName(), fromJson.getName());
|
||||||
@@ -109,7 +109,7 @@ public class TestDbJson_List extends BaseTestCase {
|
|||||||
|
|
||||||
found.setName("mod");
|
found.setName("mod");
|
||||||
LoggedSqlCollector.start();
|
LoggedSqlCollector.start();
|
||||||
Ebean.save(found);
|
DB.save(found);
|
||||||
List<String> sql = LoggedSqlCollector.stop();
|
List<String> sql = LoggedSqlCollector.stop();
|
||||||
|
|
||||||
// we don't update the phone numbers (as they are not dirty)
|
// we don't update the phone numbers (as they are not dirty)
|
||||||
@@ -122,7 +122,7 @@ public class TestDbJson_List extends BaseTestCase {
|
|||||||
found.getTags().add("three");
|
found.getTags().add("three");
|
||||||
|
|
||||||
LoggedSqlCollector.start();
|
LoggedSqlCollector.start();
|
||||||
Ebean.save(found);
|
DB.save(found);
|
||||||
List<String> sql = LoggedSqlCollector.stop();
|
List<String> sql = LoggedSqlCollector.stop();
|
||||||
|
|
||||||
// we don't update the phone numbers (as they are not dirty)
|
// we don't update the phone numbers (as they are not dirty)
|
||||||
@@ -135,7 +135,7 @@ public class TestDbJson_List extends BaseTestCase {
|
|||||||
found.getFlags().remove(42L);
|
found.getFlags().remove(42L);
|
||||||
|
|
||||||
LoggedSqlCollector.start();
|
LoggedSqlCollector.start();
|
||||||
Ebean.save(found);
|
DB.save(found);
|
||||||
List<String> sql = LoggedSqlCollector.stop();
|
List<String> sql = LoggedSqlCollector.stop();
|
||||||
|
|
||||||
// we don't update the phone numbers (as they are not dirty)
|
// we don't update the phone numbers (as they are not dirty)
|
||||||
@@ -150,7 +150,7 @@ public class TestDbJson_List extends BaseTestCase {
|
|||||||
found.getBeanMap().remove("key0");
|
found.getBeanMap().remove("key0");
|
||||||
|
|
||||||
LoggedSqlCollector.start();
|
LoggedSqlCollector.start();
|
||||||
Ebean.save(found);
|
DB.save(found);
|
||||||
List<String> sql = LoggedSqlCollector.stop();
|
List<String> sql = LoggedSqlCollector.stop();
|
||||||
|
|
||||||
// we don't update the phone numbers (as they are not dirty)
|
// we don't update the phone numbers (as they are not dirty)
|
||||||
@@ -166,13 +166,13 @@ public class TestDbJson_List extends BaseTestCase {
|
|||||||
bean.setTags(null);
|
bean.setTags(null);
|
||||||
bean.setBeanMap(null);
|
bean.setBeanMap(null);
|
||||||
|
|
||||||
Ebean.save(bean);
|
DB.save(bean);
|
||||||
|
|
||||||
EBasicJsonList found = Ebean.find(EBasicJsonList.class, bean.getId());
|
EBasicJsonList found = DB.find(EBasicJsonList.class, bean.getId());
|
||||||
|
|
||||||
assertNull(found.getPlainBean());
|
assertNull(found.getPlainBean());
|
||||||
|
|
||||||
String asJson = Ebean.json().toJson(found);
|
String asJson = DB.json().toJson(found);
|
||||||
assertNotNull(asJson);
|
assertNotNull(asJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,17 +186,16 @@ public class TestDbJson_List extends BaseTestCase {
|
|||||||
plainBean.setName("Blubb");
|
plainBean.setName("Blubb");
|
||||||
bean.getBeanMap().put("bla", plainBean);
|
bean.getBeanMap().put("bla", plainBean);
|
||||||
|
|
||||||
Ebean.save(bean);
|
DB.save(bean);
|
||||||
|
|
||||||
// set some invalid JSON content into DB
|
// set some invalid JSON content into DB
|
||||||
Ebean.update(EBasicJsonList.class)
|
DB.sqlUpdate("update ebasic_json_list set bean_map=? where id=?")
|
||||||
.set("beanMap", "blabla")
|
.setParameters("blabla", bean.getId())
|
||||||
.where().eq("id", bean.getId())
|
.execute();
|
||||||
.update();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// a normal query fails due to invalid JSON content
|
// a normal query fails due to invalid JSON content
|
||||||
Ebean.find(EBasicJsonList.class)
|
DB.find(EBasicJsonList.class)
|
||||||
.setId(bean.getId())
|
.setId(bean.getId())
|
||||||
.findOne();
|
.findOne();
|
||||||
|
|
||||||
@@ -208,7 +207,7 @@ public class TestDbJson_List extends BaseTestCase {
|
|||||||
assertThat(e.getMessage()).contains("beanMap");
|
assertThat(e.getMessage()).contains("beanMap");
|
||||||
}
|
}
|
||||||
|
|
||||||
bean = Ebean.find(EBasicJsonList.class)
|
bean = DB.find(EBasicJsonList.class)
|
||||||
.setId(bean.getId())
|
.setId(bean.getId())
|
||||||
.setAllowLoadErrors() // allow invalid JSON content
|
.setAllowLoadErrors() // allow invalid JSON content
|
||||||
.findOne();
|
.findOne();
|
||||||
@@ -220,6 +219,6 @@ public class TestDbJson_List extends BaseTestCase {
|
|||||||
.isInstanceOf(TextException.class)
|
.isInstanceOf(TextException.class)
|
||||||
.hasMessageContaining("blabla");
|
.hasMessageContaining("blabla");
|
||||||
|
|
||||||
Ebean.delete(bean);
|
DB.delete(bean);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
package org.tests.json;
|
package org.tests.json;
|
||||||
|
|
||||||
import io.ebean.BaseTestCase;
|
import io.ebean.BaseTestCase;
|
||||||
import io.ebean.Ebean;
|
import io.ebean.DB;
|
||||||
import io.ebean.Query;
|
import io.ebean.Query;
|
||||||
import io.ebean.text.json.EJson;
|
import io.ebean.text.json.EJson;
|
||||||
|
import io.ebeantest.LoggedSql;
|
||||||
import org.tests.model.json.EBasicJsonMap;
|
import org.tests.model.json.EBasicJsonMap;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.tests.model.json.EBasicJsonMapDetail;
|
import org.tests.model.json.EBasicJsonMapDetail;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@@ -29,9 +31,9 @@ public class TestJsonMapBasic extends BaseTestCase {
|
|||||||
bean.getDetails().add(new EBasicJsonMapDetail("detail1"));
|
bean.getDetails().add(new EBasicJsonMapDetail("detail1"));
|
||||||
bean.getDetails().add(new EBasicJsonMapDetail("detail2"));
|
bean.getDetails().add(new EBasicJsonMapDetail("detail2"));
|
||||||
|
|
||||||
Ebean.save(bean);
|
DB.save(bean);
|
||||||
|
|
||||||
Query<EBasicJsonMap> query1 = Ebean.find(EBasicJsonMap.class)
|
Query<EBasicJsonMap> query1 = DB.find(EBasicJsonMap.class)
|
||||||
.fetch("details")
|
.fetch("details")
|
||||||
.where().startsWith("details.name", "detail")
|
.where().startsWith("details.name", "detail")
|
||||||
.query();
|
.query();
|
||||||
@@ -40,7 +42,7 @@ public class TestJsonMapBasic extends BaseTestCase {
|
|||||||
|
|
||||||
assertThat(query1.getGeneratedSql()).contains("select distinct on (t0.id, t1.id) ");
|
assertThat(query1.getGeneratedSql()).contains("select distinct on (t0.id, t1.id) ");
|
||||||
|
|
||||||
Query<EBasicJsonMap> query2 = Ebean.find(EBasicJsonMap.class)
|
Query<EBasicJsonMap> query2 = DB.find(EBasicJsonMap.class)
|
||||||
.where().startsWith("details.name", "detail")
|
.where().startsWith("details.name", "detail")
|
||||||
.query();
|
.query();
|
||||||
query2.findList();
|
query2.findList();
|
||||||
@@ -60,9 +62,9 @@ public class TestJsonMapBasic extends BaseTestCase {
|
|||||||
bean.setName("one");
|
bean.setName("one");
|
||||||
bean.setContent(content);
|
bean.setContent(content);
|
||||||
|
|
||||||
Ebean.save(bean);
|
DB.save(bean);
|
||||||
|
|
||||||
EBasicJsonMap bean1 = Ebean.find(EBasicJsonMap.class, bean.getId());
|
EBasicJsonMap bean1 = DB.find(EBasicJsonMap.class, bean.getId());
|
||||||
|
|
||||||
assertEquals(bean.getId(), bean1.getId());
|
assertEquals(bean.getId(), bean1.getId());
|
||||||
assertEquals(bean.getName(), bean1.getName());
|
assertEquals(bean.getName(), bean1.getName());
|
||||||
@@ -70,16 +72,16 @@ public class TestJsonMapBasic extends BaseTestCase {
|
|||||||
assertEquals(18L, bean1.getContent().get("docId"));
|
assertEquals(18L, bean1.getContent().get("docId"));
|
||||||
|
|
||||||
bean1.setName("just change name");
|
bean1.setName("just change name");
|
||||||
Ebean.save(bean1);
|
DB.save(bean1);
|
||||||
|
|
||||||
// content changes detected - dirty state so included in update
|
// content changes detected - dirty state so included in update
|
||||||
Map<String, Object> content1 = bean1.getContent();
|
Map<String, Object> content1 = bean1.getContent();
|
||||||
content1.put("additional", "newValue");
|
content1.put("additional", "newValue");
|
||||||
content1.put("docId", 99L);
|
content1.put("docId", 99L);
|
||||||
bean1.setName("two");
|
bean1.setName("two");
|
||||||
Ebean.save(bean1);
|
DB.save(bean1);
|
||||||
|
|
||||||
EBasicJsonMap bean2 = Ebean.find(EBasicJsonMap.class, bean.getId());
|
EBasicJsonMap bean2 = DB.find(EBasicJsonMap.class, bean.getId());
|
||||||
|
|
||||||
// name changed and docId changed
|
// name changed and docId changed
|
||||||
assertEquals("two", bean2.getName());
|
assertEquals("two", bean2.getName());
|
||||||
@@ -89,12 +91,48 @@ public class TestJsonMapBasic extends BaseTestCase {
|
|||||||
content1.put("additional", "modValue");
|
content1.put("additional", "modValue");
|
||||||
bean1.setName("three");
|
bean1.setName("three");
|
||||||
bean1.setContent(content1);
|
bean1.setContent(content1);
|
||||||
Ebean.save(bean1);
|
DB.save(bean1);
|
||||||
|
|
||||||
EBasicJsonMap bean3 = Ebean.find(EBasicJsonMap.class, bean.getId());
|
EBasicJsonMap bean3 = DB.find(EBasicJsonMap.class, bean.getId());
|
||||||
|
|
||||||
assertEquals("three", bean3.getName());
|
assertEquals("three", bean3.getName());
|
||||||
assertEquals(99L, bean3.getContent().get("docId"));
|
assertEquals(99L, bean3.getContent().get("docId"));
|
||||||
assertEquals("modValue", bean3.getContent().get("additional"));
|
assertEquals("modValue", bean3.getContent().get("additional"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateQuery_bindingMap() throws IOException {
|
||||||
|
|
||||||
|
String s0 = "{\"docId\":22,\"contentId\":\"initialDoc\"}";
|
||||||
|
Map<String, Object> content = EJson.parseObject(s0);
|
||||||
|
|
||||||
|
EBasicJsonMap bean = new EBasicJsonMap();
|
||||||
|
bean.setName("one");
|
||||||
|
bean.setContent(content);
|
||||||
|
|
||||||
|
DB.save(bean);
|
||||||
|
|
||||||
|
String s1 = "{\"docId\":222,\"contentId\":\"updatedDoc222\"}";
|
||||||
|
Map<String, Object> content1 = EJson.parseObject(s1);
|
||||||
|
|
||||||
|
LoggedSql.start();
|
||||||
|
|
||||||
|
final int rows = DB.update(EBasicJsonMap.class)
|
||||||
|
.set("content", content1)
|
||||||
|
.where().eq("id", bean.getId())
|
||||||
|
.update();
|
||||||
|
|
||||||
|
final List<String> sql = LoggedSql.stop();
|
||||||
|
|
||||||
|
assertThat(sql).hasSize(1);
|
||||||
|
assertThat(sql.get(0)).contains("update ebasic_json_map set content=? where id = ?");
|
||||||
|
assertThat(rows).isEqualTo(1);
|
||||||
|
|
||||||
|
final EBasicJsonMap found = DB.find(EBasicJsonMap.class, bean.getId());
|
||||||
|
final Map<String, Object> content2 = found.getContent();
|
||||||
|
assertThat(content2.get("contentId")).isEqualTo("updatedDoc222");
|
||||||
|
assertThat(content2.get("docId")).isEqualTo(222L);
|
||||||
|
|
||||||
|
DB.delete(found);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user