Improve Java/SQL ORM
- Support for custom Java types and conversion for database storage - Enums are considered custom types - SQLField.name is now encapsulated as encouraged by OOP principles - SQLField.name is now auto deducted from the Java field's name in the SQLElement subclass (no more field name in the constructor) - No need to precise the SQLType of an SQLFKField (auto deducted from the target SQLField's type) via static method SQLFKField.customFK() - Support of Java type UUID (stored as CHAR(36) in database. No need to use custom getter and setters for SQLElements using UUID fields
This commit is contained in:
parent
706ae682ec
commit
0391b7a9a0
@ -7,13 +7,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import fr.pandacube.java.util.EnumUtil;
|
import org.javatuples.Pair;
|
||||||
|
|
||||||
import fr.pandacube.java.util.Log;
|
import fr.pandacube.java.util.Log;
|
||||||
import fr.pandacube.java.util.orm.SQLWhereChain.SQLBoolOp;
|
import fr.pandacube.java.util.orm.SQLWhereChain.SQLBoolOp;
|
||||||
import fr.pandacube.java.util.orm.SQLWhereComp.SQLComparator;
|
import fr.pandacube.java.util.orm.SQLWhereComp.SQLComparator;
|
||||||
|
|
||||||
import org.javatuples.Pair;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <b>ORM = Object-Relational Mapping</b>
|
* <b>ORM = Object-Relational Mapping</b>
|
||||||
*
|
*
|
||||||
@ -99,12 +98,12 @@ public final class ORM {
|
|||||||
return (SQLField<E, Integer>) SQLElement.fieldsCache.get(elemClass).get("id");
|
return (SQLField<E, Integer>) SQLElement.fieldsCache.get(elemClass).get("id");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <E extends SQLElement<E>> List<E> getByIds(Class<E> elemClass, Collection<Integer> ids)
|
public static <E extends SQLElement<E>> SQLElementList<E> getByIds(Class<E> elemClass, Collection<Integer> ids)
|
||||||
throws ORMException {
|
throws ORMException {
|
||||||
return getByIds(elemClass, ids.toArray(new Integer[ids.size()]));
|
return getByIds(elemClass, ids.toArray(new Integer[ids.size()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <E extends SQLElement<E>> List<E> getByIds(Class<E> elemClass, Integer... ids) throws ORMException {
|
public static <E extends SQLElement<E>> SQLElementList<E> getByIds(Class<E> elemClass, Integer... ids) throws ORMException {
|
||||||
SQLField<E, Integer> idField = getSQLIdField(elemClass);
|
SQLField<E, Integer> idField = getSQLIdField(elemClass);
|
||||||
SQLWhereChain where = new SQLWhereChain(SQLBoolOp.OR);
|
SQLWhereChain where = new SQLWhereChain(SQLBoolOp.OR);
|
||||||
for (Integer id : ids)
|
for (Integer id : ids)
|
||||||
@ -176,6 +175,7 @@ public final class ORM {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private static <E extends SQLElement<E>> E getElementInstance(ResultSet set, Class<E> elemClass) throws ORMException {
|
private static <E extends SQLElement<E>> E getElementInstance(ResultSet set, Class<E> elemClass) throws ORMException {
|
||||||
try {
|
try {
|
||||||
E instance = elemClass.getConstructor(int.class).newInstance(set.getInt("id"));
|
E instance = elemClass.getConstructor(int.class).newInstance(set.getInt("id"));
|
||||||
@ -184,33 +184,38 @@ public final class ORM {
|
|||||||
|
|
||||||
for (int c = 1; c <= fieldCount; c++) {
|
for (int c = 1; c <= fieldCount; c++) {
|
||||||
String fieldName = set.getMetaData().getColumnLabel(c);
|
String fieldName = set.getMetaData().getColumnLabel(c);
|
||||||
if (!instance.getFields().containsKey(fieldName)) continue;
|
|
||||||
// ignore when field is present in database but not handled by SQLElement instance
|
// ignore when field is present in database but not handled by SQLElement instance
|
||||||
@SuppressWarnings("unchecked")
|
if (!instance.getFields().containsKey(fieldName)) continue;
|
||||||
|
|
||||||
SQLField<E, Object> sqlField = (SQLField<E, Object>) instance.getFields().get(fieldName);
|
SQLField<E, Object> sqlField = (SQLField<E, Object>) instance.getFields().get(fieldName);
|
||||||
if (sqlField.type.getJavaType().isEnum()) {
|
|
||||||
// JDBC ne supporte pas les enums
|
boolean customType = sqlField.type instanceof SQLCustomType;
|
||||||
String enumStrValue = set.getString(c);
|
|
||||||
if (enumStrValue == null || set.wasNull()) instance.set(sqlField, null, false);
|
Object val = set.getObject(c,
|
||||||
else {
|
(Class<?>)(customType ? ((SQLCustomType<?, ?>)sqlField.type).intermediateJavaType
|
||||||
Enum<?> enumValue = EnumUtil.searchUncheckedEnum(sqlField.type.getJavaType(), enumStrValue);
|
: sqlField.type.getJavaType()));
|
||||||
if (enumValue == null) throw new ORMException("The enum constant '" + enumStrValue
|
|
||||||
+ "' is not found in enum class " + sqlField.type.getJavaType().getName());
|
if (val == null || set.wasNull()) {
|
||||||
instance.set(sqlField, enumValue, false);
|
instance.set(sqlField, null, false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Object val = set.getObject(c, sqlField.type.getJavaType());
|
if (customType) {
|
||||||
if (val == null || set.wasNull()) instance.set(sqlField, null, false);
|
try {
|
||||||
else
|
val = ((SQLCustomType<Object, Object>)sqlField.type).dbToJavaConv.apply(val);
|
||||||
instance.set(sqlField, val, false);
|
} catch (Exception e) {
|
||||||
|
throw new ORMException("Error while converting value of field '"+sqlField.getName()+"' with SQLCustomType from "+((SQLCustomType<Object, Object>)sqlField.type).intermediateJavaType
|
||||||
|
+"(jdbc source) to "+sqlField.type.getJavaType()+"(java destination). The original value is '"+val.toString()+"'", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instance.set(sqlField, val, false);
|
||||||
// la valeur venant de la BDD est marqué comme "non modifié"
|
// la valeur venant de la BDD est marqué comme "non modifié"
|
||||||
// dans l'instance
|
// dans l'instance car le constructeur de l'instance met
|
||||||
// car le constructeur de l'instance met tout les champs comme
|
// tout les champs comme modifiés
|
||||||
// modifiés
|
instance.modifiedSinceLastSave.remove(sqlField.getName());
|
||||||
instance.modifiedSinceLastSave.remove(sqlField.name);
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!instance.isValidForSave()) throw new ORMException(
|
if (!instance.isValidForSave()) throw new ORMException(
|
||||||
|
32
src/main/java/fr/pandacube/java/util/orm/SQLCustomType.java
Normal file
32
src/main/java/fr/pandacube/java/util/orm/SQLCustomType.java
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package fr.pandacube.java.util.orm;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Marc
|
||||||
|
*
|
||||||
|
* @param <IT> intermediate type, the type of the value transmitted to the JDBC
|
||||||
|
* @param <JT> Java type
|
||||||
|
*/
|
||||||
|
public class SQLCustomType<IT, JT> extends SQLType<JT> {
|
||||||
|
|
||||||
|
public final Class<IT> intermediateJavaType;
|
||||||
|
public final Function<IT, JT> dbToJavaConv;
|
||||||
|
public final Function<JT, IT> javaToDbConv;
|
||||||
|
|
||||||
|
protected SQLCustomType(SQLType<IT> type, Class<JT> javaT, Function<IT, JT> dbToJava, Function<JT, IT> javaToDb) {
|
||||||
|
this(type.sqlDeclaration, type.getJavaType(), javaT, dbToJava, javaToDb);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SQLCustomType(String sqlD, Class<IT> intermediateJavaT, Class<JT> javaT, Function<IT, JT> dbToJava, Function<JT, IT> javaToDb) {
|
||||||
|
super(sqlD, javaT);
|
||||||
|
intermediateJavaType = intermediateJavaT;
|
||||||
|
dbToJavaConv = dbToJava;
|
||||||
|
javaToDbConv = javaToDb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// tester en local
|
||||||
|
|
||||||
|
}
|
@ -52,7 +52,9 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
fields = new SQLFieldMap<>((Class<E>)getClass());
|
fields = new SQLFieldMap<>((Class<E>)getClass());
|
||||||
|
|
||||||
// le champ id commun à toutes les tables
|
// le champ id commun à toutes les tables
|
||||||
fields.addField(new SQLField<>("id", SQLType.INT, false, true, 0));
|
SQLField<E, Integer> idF = new SQLField<>(SQLType.INT, false, true, 0);
|
||||||
|
idF.setName("id");
|
||||||
|
fields.addField(idF);
|
||||||
|
|
||||||
generateFields(fields);
|
generateFields(fields);
|
||||||
fieldsCache.put((Class<E>)getClass(), fields);
|
fieldsCache.put((Class<E>)getClass(), fields);
|
||||||
@ -91,6 +93,7 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
else if (f.canBeNull || (f.autoIncrement && !stored)) set(f, null);
|
else if (f.canBeNull || (f.autoIncrement && !stored)) set(f, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
protected void generateFields(SQLFieldMap<E> listToFill) {
|
protected void generateFields(SQLFieldMap<E> listToFill) {
|
||||||
|
|
||||||
java.lang.reflect.Field[] declaredFields = getClass().getDeclaredFields();
|
java.lang.reflect.Field[] declaredFields = getClass().getDeclaredFields();
|
||||||
@ -100,7 +103,11 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
try {
|
try {
|
||||||
Object val = field.get(null);
|
Object val = field.get(null);
|
||||||
if (val == null || !(val instanceof SQLField)) continue;
|
if (val == null || !(val instanceof SQLField)) continue;
|
||||||
|
SQLField<E, ?> checkedF = (SQLField<E, ?>) val;
|
||||||
|
checkedF.setName(field.getName());
|
||||||
|
if (listToFill.containsKey(checkedF.getName())) throw new IllegalArgumentException(
|
||||||
|
"SQLField " + checkedF.getName() + " already exist in " + getClass().getName());
|
||||||
|
checkedF.setSQLElementType((Class<E>) getClass());
|
||||||
listToFill.addField((SQLField<?, ?>) val);
|
listToFill.addField((SQLField<?, ?>) val);
|
||||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||||
Log.severe("Can't get value of static field " + field.toString(), e);
|
Log.severe("Can't get value of static field " + field.toString(), e);
|
||||||
@ -124,30 +131,30 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
/* package */ <T> void set(SQLField<E, T> sqlField, T value, boolean setModified) {
|
/* package */ <T> void set(SQLField<E, T> sqlField, T value, boolean setModified) {
|
||||||
if (sqlField == null) throw new IllegalArgumentException("sqlField can't be null");
|
if (sqlField == null) throw new IllegalArgumentException("sqlField can't be null");
|
||||||
if (!fields.containsValue(sqlField))
|
if (!fields.containsValue(sqlField))
|
||||||
throw new IllegalArgumentException(sqlField.getSQLElementType().getName()+sqlField.name + " is not a SQLField of " + getClass().getName());
|
throw new IllegalArgumentException(sqlField.getSQLElementType().getName()+sqlField.getName() + " is not a SQLField of " + getClass().getName());
|
||||||
|
|
||||||
boolean modify = false;
|
boolean modify = false;
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
if (sqlField.canBeNull || (sqlField.autoIncrement && !stored)) modify = true;
|
if (sqlField.canBeNull || (sqlField.autoIncrement && !stored)) modify = true;
|
||||||
else
|
else
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"SQLField '" + sqlField.name + "' of " + getClass().getName() + " is a NOT NULL field");
|
"SQLField '" + sqlField.getName() + "' of " + getClass().getName() + " is a NOT NULL field");
|
||||||
}
|
}
|
||||||
else if (sqlField.type.isAssignableFrom(value)) modify = true;
|
else if (sqlField.type.isAssignableFrom(value)) modify = true;
|
||||||
else
|
else
|
||||||
throw new IllegalArgumentException("SQLField '" + sqlField.name + "' of " + getClass().getName()
|
throw new IllegalArgumentException("SQLField '" + sqlField.getName() + "' of " + getClass().getName()
|
||||||
+ " type is '" + sqlField.type.toString() + "' and can't accept values of type "
|
+ " type is '" + sqlField.type.toString() + "' and can't accept values of type "
|
||||||
+ value.getClass().getName());
|
+ value.getClass().getName());
|
||||||
|
|
||||||
if (modify) if (!values.containsKey(sqlField)) {
|
if (modify) if (!values.containsKey(sqlField)) {
|
||||||
values.put(sqlField, value);
|
values.put(sqlField, value);
|
||||||
if (setModified) modifiedSinceLastSave.add(sqlField.name);
|
if (setModified) modifiedSinceLastSave.add(sqlField.getName());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Object oldVal = values.get(sqlField);
|
Object oldVal = values.get(sqlField);
|
||||||
if (!Objects.equals(oldVal, value)) {
|
if (!Objects.equals(oldVal, value)) {
|
||||||
values.put(sqlField, value);
|
values.put(sqlField, value);
|
||||||
if (setModified) modifiedSinceLastSave.add(sqlField.name);
|
if (setModified) modifiedSinceLastSave.add(sqlField.getName());
|
||||||
}
|
}
|
||||||
// sinon, rien n'est modifié
|
// sinon, rien n'est modifié
|
||||||
}
|
}
|
||||||
@ -161,7 +168,7 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
T val = (T) values.get(field);
|
T val = (T) values.get(field);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("The field '" + field.name + "' in this instance of " + getClass().getName()
|
throw new IllegalArgumentException("The field '" + field.getName() + "' in this instance of " + getClass().getName()
|
||||||
+ " does not exist or is not set");
|
+ " does not exist or is not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,13 +186,13 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
private Map<SQLField<E, ?>, Object> getOnlyModifiedValues() {
|
private Map<SQLField<E, ?>, Object> getOnlyModifiedValues() {
|
||||||
Map<SQLField<E, ?>, Object> modifiedValues = new LinkedHashMap<>();
|
Map<SQLField<E, ?>, Object> modifiedValues = new LinkedHashMap<>();
|
||||||
values.forEach((k, v) -> {
|
values.forEach((k, v) -> {
|
||||||
if (modifiedSinceLastSave.contains(k.name)) modifiedValues.put(k, v);
|
if (modifiedSinceLastSave.contains(k.getName())) modifiedValues.put(k, v);
|
||||||
});
|
});
|
||||||
return modifiedValues;
|
return modifiedValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isModified(SQLField<E, ?> field) {
|
public boolean isModified(SQLField<E, ?> field) {
|
||||||
return modifiedSinceLastSave.contains(field.name);
|
return modifiedSinceLastSave.contains(field.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@ -214,16 +221,8 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
List<Object> psValues = new ArrayList<>();
|
List<Object> psValues = new ArrayList<>();
|
||||||
|
|
||||||
for (Map.Entry<SQLField<E, ?>, Object> entry : modifiedValues.entrySet()) {
|
for (Map.Entry<SQLField<E, ?>, Object> entry : modifiedValues.entrySet()) {
|
||||||
sql += entry.getKey().name + " = ? ,";
|
sql += entry.getKey().getName() + " = ? ,";
|
||||||
if (entry.getKey().type.getJavaType().isEnum()) // prise en
|
addValueToSQLObjectList(psValues, entry.getKey(), entry.getValue());
|
||||||
// charge
|
|
||||||
// enum (non
|
|
||||||
// prise en
|
|
||||||
// charge
|
|
||||||
// par JDBC)
|
|
||||||
psValues.add(((Enum<?>) entry.getValue()).name());
|
|
||||||
else
|
|
||||||
psValues.add(entry.getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sql.length() > 0) sql = sql.substring(0, sql.length() - 1);
|
if (sql.length() > 0) sql = sql.substring(0, sql.length() - 1);
|
||||||
@ -260,16 +259,8 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
concat_vals += " ? ";
|
concat_vals += " ? ";
|
||||||
concat_fields += entry.getKey().name;
|
concat_fields += entry.getKey().getName();
|
||||||
if (entry.getKey().type.getJavaType().isEnum()) // prise en
|
addValueToSQLObjectList(psValues, entry.getKey(), entry.getValue());
|
||||||
// charge
|
|
||||||
// enum (non
|
|
||||||
// prise en
|
|
||||||
// charge
|
|
||||||
// par JDBC)
|
|
||||||
psValues.add(((Enum<?>) entry.getValue()).name());
|
|
||||||
else
|
|
||||||
psValues.add(entry.getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PreparedStatement ps = conn.prepareStatement(
|
PreparedStatement ps = conn.prepareStatement(
|
||||||
@ -305,6 +296,20 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
Log.debug(toStringStatement);
|
Log.debug(toStringStatement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
protected static <E extends SQLElement<E>> void addValueToSQLObjectList(List<Object> list, SQLField<E, ?> field, Object jValue) throws ORMException {
|
||||||
|
if (jValue != null && field.type instanceof SQLCustomType) {
|
||||||
|
try {
|
||||||
|
jValue = ((SQLCustomType)field.type).javaToDbConv.apply(jValue);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ORMException("Error while converting value of field '"+field.getName()+"' with SQLCustomType from "+field.type.getJavaType()
|
||||||
|
+"(java source) to "+((SQLCustomType<?, ?>)field.type).intermediateJavaType+"(jdbc destination). The original value is '"+jValue.toString()+"'", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list.add(jValue);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isStored() {
|
public boolean isStored() {
|
||||||
return stored;
|
return stored;
|
||||||
}
|
}
|
||||||
@ -346,7 +351,7 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
stored = false;
|
stored = false;
|
||||||
id = 0;
|
id = 0;
|
||||||
modifiedSinceLastSave.clear();
|
modifiedSinceLastSave.clear();
|
||||||
values.forEach((k, v) -> modifiedSinceLastSave.add(k.name));
|
values.forEach((k, v) -> modifiedSinceLastSave.add(k.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class SQLFieldMap<E extends SQLElement<E>> extends LinkedHashMap<String, SQLField<E, ?>> {
|
protected static class SQLFieldMap<E extends SQLElement<E>> extends LinkedHashMap<String, SQLField<E, ?>> {
|
||||||
@ -360,12 +365,12 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
|
|
||||||
private void addField(SQLField<?, ?> f) {
|
private void addField(SQLField<?, ?> f) {
|
||||||
if (f == null) return;
|
if (f == null) return;
|
||||||
if (containsKey(f.name)) throw new IllegalArgumentException(
|
if (containsKey(f.getName())) throw new IllegalArgumentException(
|
||||||
"SQLField " + f.name + " already exist in " + sqlElemClass.getName());
|
"SQLField " + f.getName() + " already exist in " + sqlElemClass.getName());
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
SQLField<E, ?> checkedF = (SQLField<E, ?>) f;
|
SQLField<E, ?> checkedF = (SQLField<E, ?>) f;
|
||||||
checkedF.setSQLElementType(sqlElemClass);
|
checkedF.setSQLElementType(sqlElemClass);
|
||||||
put(checkedF.name, checkedF);
|
put(checkedF.getName(), checkedF);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -376,9 +381,9 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
|
|
||||||
for (SQLField<E, ?> f : fields.values())
|
for (SQLField<E, ?> f : fields.values())
|
||||||
try {
|
try {
|
||||||
b.append(f.name, get(f));
|
b.append(f.getName(), get(f));
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
b.append(f.name, "(Undefined)");
|
b.append(f.getName(), "(Undefined)");
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.toString();
|
return b.toString();
|
||||||
@ -402,7 +407,7 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
|||||||
public JsonObject asJsonObject() {
|
public JsonObject asJsonObject() {
|
||||||
JsonObject json = new JsonObject();
|
JsonObject json = new JsonObject();
|
||||||
for (SQLField<E, ?> f : getFields().values()) {
|
for (SQLField<E, ?> f : getFields().values()) {
|
||||||
json.add(f.name, new Gson().toJsonTree(get(f)));
|
json.add(f.getName(), new Gson().toJsonTree(get(f)));
|
||||||
}
|
}
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ public class SQLElementList<E extends SQLElement<E>> extends ArrayList<E> {
|
|||||||
public synchronized <T> void setCommon(SQLField<E, T> field, T value) {
|
public synchronized <T> void setCommon(SQLField<E, T> field, T value) {
|
||||||
if (field == null)
|
if (field == null)
|
||||||
throw new IllegalArgumentException("field can't be null");
|
throw new IllegalArgumentException("field can't be null");
|
||||||
if (field.name == "id")
|
if (field.getName() == "id")
|
||||||
throw new IllegalArgumentException("Can't modify id field in a SQLElementList");
|
throw new IllegalArgumentException("Can't modify id field in a SQLElementList");
|
||||||
|
|
||||||
Class<E> elemClass = field.getSQLElementType();
|
Class<E> elemClass = field.getSQLElementType();
|
||||||
@ -78,7 +78,7 @@ public class SQLElementList<E extends SQLElement<E>> extends ArrayList<E> {
|
|||||||
*
|
*
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
public synchronized void saveCommon() throws SQLException {
|
public synchronized void saveCommon() throws ORMException {
|
||||||
List<E> storedEl = getStoredEl();
|
List<E> storedEl = getStoredEl();
|
||||||
if (storedEl.isEmpty()) return;
|
if (storedEl.isEmpty()) return;
|
||||||
|
|
||||||
@ -86,12 +86,12 @@ public class SQLElementList<E extends SQLElement<E>> extends ArrayList<E> {
|
|||||||
List<Object> psValues = new ArrayList<>();
|
List<Object> psValues = new ArrayList<>();
|
||||||
|
|
||||||
for (Map.Entry<SQLField<E, ?>, Object> entry : modifiedValues.entrySet()) {
|
for (Map.Entry<SQLField<E, ?>, Object> entry : modifiedValues.entrySet()) {
|
||||||
sqlSet += entry.getKey().name + " = ? ,";
|
sqlSet += entry.getKey().getName() + " = ? ,";
|
||||||
if (entry.getKey().type.getJavaType().isEnum()) // prise en charge
|
SQLElement.addValueToSQLObjectList(psValues, entry.getKey(), entry.getValue());
|
||||||
// enum (non prise
|
if (entry.getKey().type.getJavaType().isEnum()) {
|
||||||
// en charge par
|
// prise en charge enum (non prise en charge par JDBC)
|
||||||
// JDBC)
|
|
||||||
psValues.add(((Enum<?>) entry.getValue()).name());
|
psValues.add(((Enum<?>) entry.getValue()).name());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
psValues.add(entry.getValue());
|
psValues.add(entry.getValue());
|
||||||
}
|
}
|
||||||
@ -106,9 +106,9 @@ public class SQLElementList<E extends SQLElement<E>> extends ArrayList<E> {
|
|||||||
sqlWhere += "id = " + el.getId();
|
sqlWhere += "id = " + el.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
PreparedStatement ps = ORM.getConnection().getNativeConnection()
|
try(PreparedStatement ps = ORM.getConnection().getNativeConnection()
|
||||||
.prepareStatement("UPDATE " + storedEl.get(0).tableName() + " SET " + sqlSet + " WHERE " + sqlWhere);
|
.prepareStatement("UPDATE " + storedEl.get(0).tableName() + " SET " + sqlSet + " WHERE " + sqlWhere);) {
|
||||||
try {
|
|
||||||
|
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for (Object val : psValues)
|
for (Object val : psValues)
|
||||||
@ -118,8 +118,8 @@ public class SQLElementList<E extends SQLElement<E>> extends ArrayList<E> {
|
|||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
|
|
||||||
applyNewValuesToElements(storedEl);
|
applyNewValuesToElements(storedEl);
|
||||||
} finally {
|
} catch (SQLException e) {
|
||||||
ps.close();
|
throw new ORMException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,36 +7,33 @@ public class SQLFKField<E extends SQLElement<E>, T, F extends SQLElement<F>> ext
|
|||||||
private SQLField<F, T> sqlForeignKeyField;
|
private SQLField<F, T> sqlForeignKeyField;
|
||||||
private Class<F> sqlForeignKeyElemClass;
|
private Class<F> sqlForeignKeyElemClass;
|
||||||
|
|
||||||
public SQLFKField(String n, SQLType<T> t, boolean nul, Class<F> fkEl, SQLField<F, T> fkF) {
|
protected SQLFKField(SQLType<T> t, boolean nul, T deflt, Class<F> fkEl, SQLField<F, T> fkF) {
|
||||||
super(n, t, nul);
|
super(t, nul, deflt);
|
||||||
construct(fkEl, fkF);
|
construct(fkEl, fkF);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SQLFKField(String n, SQLType<T> t, boolean nul, T deflt, Class<F> fkEl, SQLField<F, T> fkF) {
|
public static <E extends SQLElement<E>, F extends SQLElement<F>> SQLFKField<E, Integer, F> idFK(boolean nul, Class<F> fkEl) {
|
||||||
super(n, t, nul, deflt);
|
return idFK(nul, null, fkEl);
|
||||||
construct(fkEl, fkF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <E extends SQLElement<E>, F extends SQLElement<F>> SQLFKField<E, Integer, F> idFK(String n, SQLType<Integer> t, boolean nul,
|
public static <E extends SQLElement<E>, F extends SQLElement<F>> SQLFKField<E, Integer, F> idFK(boolean nul, Integer deflt, Class<F> fkEl) {
|
||||||
Class<F> fkEl) {
|
|
||||||
if (fkEl == null) throw new IllegalArgumentException("foreignKeyElement can't be null");
|
if (fkEl == null) throw new IllegalArgumentException("foreignKeyElement can't be null");
|
||||||
try {
|
try {
|
||||||
return new SQLFKField<>(n, t, nul, fkEl, ORM.getSQLIdField(fkEl));
|
SQLField<F, Integer> f = ORM.getSQLIdField(fkEl);
|
||||||
|
return new SQLFKField<>(f.type, nul, deflt, fkEl, f);
|
||||||
} catch (ORMInitTableException e) {
|
} catch (ORMInitTableException e) {
|
||||||
Log.severe("Can't create Foreign key Field called '" + n + "'", e);
|
Log.severe("Can't create Foreign key Field targetting id field of '"+fkEl+"'", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <E extends SQLElement<E>, F extends SQLElement<F>> SQLFKField<E, Integer, F> idFKField(String n, SQLType<Integer> t, boolean nul,
|
public static <E extends SQLElement<E>, T, F extends SQLElement<F>> SQLFKField<E, T, F> customFK(boolean nul, Class<F> fkEl, SQLField<F, T> fkF) {
|
||||||
Integer deflt, Class<F> fkEl) {
|
return customFK(nul, null, fkEl, fkF);
|
||||||
if (fkEl == null) throw new IllegalArgumentException("foreignKeyElement can't be null");
|
|
||||||
try {
|
|
||||||
return new SQLFKField<>(n, t, nul, deflt, fkEl, ORM.getSQLIdField(fkEl));
|
|
||||||
} catch (ORMInitTableException e) {
|
|
||||||
Log.severe("Can't create Foreign key Field called '" + n + "'", e);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <E extends SQLElement<E>, T, F extends SQLElement<F>> SQLFKField<E, T, F> customFK(boolean nul, T deflt, Class<F> fkEl, SQLField<F, T> fkF) {
|
||||||
|
if (fkEl == null) throw new IllegalArgumentException("foreignKeyElement can't be null");
|
||||||
|
return new SQLFKField<>(fkF.type, nul, deflt, fkEl, fkF);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void construct(Class<F> fkEl, SQLField<F, T> fkF) {
|
private void construct(Class<F> fkEl, SQLField<F, T> fkF) {
|
||||||
|
@ -8,36 +8,35 @@ import org.javatuples.Pair;
|
|||||||
public class SQLField<E extends SQLElement<E>, T> {
|
public class SQLField<E extends SQLElement<E>, T> {
|
||||||
|
|
||||||
private Class<E> sqlElemClass;
|
private Class<E> sqlElemClass;
|
||||||
public final String name;
|
private String name = null;
|
||||||
public final SQLType<T> type;
|
public final SQLType<T> type;
|
||||||
public final boolean canBeNull;
|
public final boolean canBeNull;
|
||||||
public final boolean autoIncrement;
|
public final boolean autoIncrement;
|
||||||
/* package */ final T defaultValue;
|
/* package */ final T defaultValue;
|
||||||
|
|
||||||
public SQLField(String n, SQLType<T> t, boolean nul, boolean autoIncr, T deflt) {
|
public SQLField(SQLType<T> t, boolean nul, boolean autoIncr, T deflt) {
|
||||||
name = n;
|
|
||||||
type = t;
|
type = t;
|
||||||
canBeNull = nul;
|
canBeNull = nul;
|
||||||
autoIncrement = autoIncr;
|
autoIncrement = autoIncr;
|
||||||
defaultValue = deflt;
|
defaultValue = deflt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SQLField(String n, SQLType<T> t, boolean nul) {
|
public SQLField(SQLType<T> t, boolean nul) {
|
||||||
this(n, t, nul, false, null);
|
this(t, nul, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SQLField(String n, SQLType<T> t, boolean nul, boolean autoIncr) {
|
public SQLField(SQLType<T> t, boolean nul, boolean autoIncr) {
|
||||||
this(n, t, nul, autoIncr, null);
|
this(t, nul, autoIncr, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SQLField(String n, SQLType<T> t, boolean nul, T deflt) {
|
public SQLField(SQLType<T> t, boolean nul, T deflt) {
|
||||||
this(n, t, nul, false, deflt);
|
this(t, nul, false, deflt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ Pair<String, List<Object>> forSQLPreparedStatement() {
|
/* package */ Pair<String, List<Object>> forSQLPreparedStatement() {
|
||||||
List<Object> params = new ArrayList<>(1);
|
List<Object> params = new ArrayList<>(1);
|
||||||
if (defaultValue != null && !autoIncrement) params.add(defaultValue);
|
if (defaultValue != null && !autoIncrement) params.add(defaultValue);
|
||||||
return new Pair<>(name + " " + type.toString() + (canBeNull ? " NULL" : " NOT NULL")
|
return new Pair<>(getName() + " " + type.toString() + (canBeNull ? " NULL" : " NOT NULL")
|
||||||
+ (autoIncrement ? " AUTO_INCREMENT" : "")
|
+ (autoIncrement ? " AUTO_INCREMENT" : "")
|
||||||
+ ((defaultValue == null || autoIncrement) ? "" : " DEFAULT ?"), params);
|
+ ((defaultValue == null || autoIncrement) ? "" : " DEFAULT ?"), params);
|
||||||
}
|
}
|
||||||
@ -50,6 +49,14 @@ public class SQLField<E extends SQLElement<E>, T> {
|
|||||||
return sqlElemClass;
|
return sqlElemClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* package */ void setName(String n) {
|
||||||
|
name = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <b>Don't use this {@link #toString()} method in a SQL query, because
|
* <b>Don't use this {@link #toString()} method in a SQL query, because
|
||||||
* the default value is not escaped correctly</b>
|
* the default value is not escaped correctly</b>
|
||||||
@ -67,14 +74,14 @@ public class SQLField<E extends SQLElement<E>, T> {
|
|||||||
if (obj == null) return false;
|
if (obj == null) return false;
|
||||||
if (!(obj instanceof SQLField)) return false;
|
if (!(obj instanceof SQLField)) return false;
|
||||||
SQLField<?, ?> f = (SQLField<?, ?>) obj;
|
SQLField<?, ?> f = (SQLField<?, ?>) obj;
|
||||||
if (!f.name.equals(name)) return false;
|
if (!f.getName().equals(getName())) return false;
|
||||||
if (!f.sqlElemClass.equals(sqlElemClass)) return false;
|
if (!f.sqlElemClass.equals(sqlElemClass)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return name.hashCode() + sqlElemClass.hashCode();
|
return getName().hashCode() + sqlElemClass.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ public class SQLOrderBy {
|
|||||||
for (OBField f : orderByFields) {
|
for (OBField f : orderByFields) {
|
||||||
if (!first) ret += ", ";
|
if (!first) ret += ", ";
|
||||||
first = false;
|
first = false;
|
||||||
ret += f.field.name + " " + f.direction.name();
|
ret += f.field.getName() + " " + f.direction.name();
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
package fr.pandacube.java.util.orm;
|
package fr.pandacube.java.util.orm;
|
||||||
|
|
||||||
import java.sql.Date;
|
import java.sql.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import fr.pandacube.java.util.EnumUtil;
|
||||||
|
|
||||||
public class SQLType<T> {
|
public class SQLType<T> {
|
||||||
|
|
||||||
private final String sqlType;
|
protected final String sqlDeclaration;
|
||||||
private final String sqlTypeParam;
|
|
||||||
private final Class<T> javaTypes;
|
private final Class<T> javaTypes;
|
||||||
|
|
||||||
public SQLType(String sqlT, String sqlP, Class<T> javaT) {
|
protected SQLType(String sqlD, Class<T> javaT) {
|
||||||
sqlType = sqlT;
|
sqlDeclaration = sqlD;
|
||||||
sqlTypeParam = sqlP;
|
|
||||||
javaTypes = javaT;
|
javaTypes = javaT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return sqlType + sqlTypeParam;
|
return sqlDeclaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAssignableFrom(Object val) {
|
public boolean isAssignableFrom(Object val) {
|
||||||
@ -39,37 +40,38 @@ public class SQLType<T> {
|
|||||||
return javaTypes;
|
return javaTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final SQLType<Boolean> BOOLEAN = new SQLType<>("BOOLEAN", "", Boolean.class);
|
public static final SQLType<Boolean> BOOLEAN = new SQLType<>("BOOLEAN", Boolean.class);
|
||||||
|
|
||||||
public static final SQLType<Byte> TINYINT = new SQLType<>("TINYINT", "", Byte.class);
|
public static final SQLType<Byte> TINYINT = new SQLType<>("TINYINT", Byte.class);
|
||||||
public static final SQLType<Byte> BYTE = TINYINT;
|
public static final SQLType<Byte> BYTE = TINYINT;
|
||||||
|
|
||||||
public static final SQLType<Short> SMALLINT = new SQLType<>("SMALLINT", "", Short.class);
|
public static final SQLType<Short> SMALLINT = new SQLType<>("SMALLINT", Short.class);
|
||||||
public static final SQLType<Short> SHORT = SMALLINT;
|
public static final SQLType<Short> SHORT = SMALLINT;
|
||||||
|
|
||||||
public static final SQLType<Integer> INT = new SQLType<>("INT", "", Integer.class);
|
public static final SQLType<Integer> INT = new SQLType<>("INT", Integer.class);
|
||||||
public static final SQLType<Integer> INTEGER = INT;
|
public static final SQLType<Integer> INTEGER = INT;
|
||||||
|
|
||||||
public static final SQLType<Long> BIGINT = new SQLType<>("BIGINT", "", Long.class);
|
public static final SQLType<Long> BIGINT = new SQLType<>("BIGINT", Long.class);
|
||||||
public static final SQLType<Long> LONG = BIGINT;
|
public static final SQLType<Long> LONG = BIGINT;
|
||||||
|
|
||||||
public static final SQLType<Date> DATE = new SQLType<>("DATE", "", Date.class);
|
public static final SQLType<Date> DATE = new SQLType<>("DATE", Date.class);
|
||||||
|
|
||||||
public static final SQLType<Float> FLOAT = new SQLType<>("FLOAT", "", Float.class);
|
public static final SQLType<Float> FLOAT = new SQLType<>("FLOAT", Float.class);
|
||||||
|
|
||||||
public static final SQLType<Double> DOUBLE = new SQLType<>("DOUBLE", "", Double.class);
|
public static final SQLType<Double> DOUBLE = new SQLType<>("DOUBLE", Double.class);
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static final SQLType<String> CHAR(int charCount) {
|
public static final SQLType<String> CHAR(int charCount) {
|
||||||
if (charCount <= 0) throw new IllegalArgumentException("charCount must be positive.");
|
if (charCount <= 0) throw new IllegalArgumentException("charCount must be positive.");
|
||||||
return new SQLType<>("CHAR", "(" + charCount + ")", String.class);
|
return new SQLType<>("CHAR(" + charCount + ")", String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final SQLType<String> VARCHAR(int charCount) {
|
public static final SQLType<String> VARCHAR(int charCount) {
|
||||||
if (charCount <= 0) throw new IllegalArgumentException("charCount must be positive.");
|
if (charCount <= 0) throw new IllegalArgumentException("charCount must be positive.");
|
||||||
return new SQLType<>("VARCHAR", "(" + charCount + ")", String.class);
|
return new SQLType<>("VARCHAR(" + charCount + ")", String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final SQLType<String> TEXT = new SQLType<>("TEXT", "", String.class);
|
public static final SQLType<String> TEXT = new SQLType<>("TEXT", String.class);
|
||||||
public static final SQLType<String> STRING = TEXT;
|
public static final SQLType<String> STRING = TEXT;
|
||||||
|
|
||||||
public static final <T extends Enum<T>> SQLType<T> ENUM(Class<T> enumType) {
|
public static final <T extends Enum<T>> SQLType<T> ENUM(Class<T> enumType) {
|
||||||
@ -84,7 +86,10 @@ public class SQLType<T> {
|
|||||||
}
|
}
|
||||||
enumStr += "'";
|
enumStr += "'";
|
||||||
|
|
||||||
return new SQLType<>("VARCHAR", "(" + enumStr + ")", enumType);
|
return new SQLCustomType<>("VARCHAR(" + enumStr + ")", String.class, enumType, s -> EnumUtil.searchEnum(enumType, s), Enum::name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static final SQLType<UUID> CHAR36_UUID = new SQLCustomType<>(SQLType.CHAR(36), UUID.class, UUID::fromString, UUID::toString);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,20 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.javatuples.Pair;
|
import org.javatuples.Pair;
|
||||||
|
|
||||||
|
import fr.pandacube.java.util.Log;
|
||||||
|
|
||||||
public abstract class SQLWhere {
|
public abstract class SQLWhere {
|
||||||
|
|
||||||
public abstract Pair<String, List<Object>> toSQL();
|
public abstract Pair<String, List<Object>> toSQL() throws ORMException;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
try {
|
||||||
return toSQL().getValue0();
|
return toSQL().getValue0();
|
||||||
|
} catch (ORMException e) {
|
||||||
|
Log.warning(e);
|
||||||
|
return "[SQLWhere.toString() error (see logs)]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ public class SQLWhereChain extends SQLWhere {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<String, List<Object>> toSQL() {
|
public Pair<String, List<Object>> toSQL() throws ORMException {
|
||||||
String sql = "";
|
String sql = "";
|
||||||
List<Object> params = new ArrayList<>();
|
List<Object> params = new ArrayList<>();
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
|
@ -27,19 +27,24 @@ public class SQLWhereComp extends SQLWhere {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<String, List<Object>> toSQL() {
|
public Pair<String, List<Object>> toSQL() throws ORMException {
|
||||||
List<Object> params = new ArrayList<>();
|
List<Object> params = new ArrayList<>();
|
||||||
params.add(right);
|
SQLElement.addValueToSQLObjectList(params, left, right);
|
||||||
return new Pair<>(left.name + " " + comp.sql + " ? ", params);
|
return new Pair<>(left.getName() + " " + comp.sql + " ? ", params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SQLComparator {
|
public enum SQLComparator {
|
||||||
/** Equivalent to SQL "<code>=</code>" */
|
/** Equivalent to SQL "<code>=</code>" */
|
||||||
EQ("="), /** Equivalent to SQL "<code>></code>" */
|
EQ("="),
|
||||||
GT(">"), /** Equivalent to SQL "<code>>=</code>" */
|
/** Equivalent to SQL "<code>></code>" */
|
||||||
GEQ(">="), /** Equivalent to SQL "<code><</code>" */
|
GT(">"),
|
||||||
LT("<"), /** Equivalent to SQL "<code><=</code>" */
|
/** Equivalent to SQL "<code>>=</code>" */
|
||||||
LEQ("<="), /** Equivalent to SQL "<code>!=</code>" */
|
GEQ(">="),
|
||||||
|
/** Equivalent to SQL "<code><</code>" */
|
||||||
|
LT("<"),
|
||||||
|
/** Equivalent to SQL "<code><=</code>" */
|
||||||
|
LEQ("<="),
|
||||||
|
/** Equivalent to SQL "<code>!=</code>" */
|
||||||
NEQ("!=");
|
NEQ("!=");
|
||||||
|
|
||||||
public final String sql;
|
public final String sql;
|
||||||
|
@ -27,7 +27,7 @@ public class SQLWhereLike extends SQLWhere {
|
|||||||
public Pair<String, List<Object>> toSQL() {
|
public Pair<String, List<Object>> toSQL() {
|
||||||
ArrayList<Object> params = new ArrayList<>();
|
ArrayList<Object> params = new ArrayList<>();
|
||||||
params.add(likeExpr);
|
params.add(likeExpr);
|
||||||
return new Pair<>(field.name + " LIKE ? ", params);
|
return new Pair<>(field.getName() + " LIKE ? ", params);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,14 +23,14 @@ public class SQLWhereNull extends SQLWhere {
|
|||||||
if (field == null) throw new IllegalArgumentException("field can't be null");
|
if (field == null) throw new IllegalArgumentException("field can't be null");
|
||||||
if (!field.canBeNull) Log.getLogger().log(Level.WARNING,
|
if (!field.canBeNull) Log.getLogger().log(Level.WARNING,
|
||||||
"Useless : Trying to check IS [NOT] NULL on the field " + field.getSQLElementType().getName() + "#"
|
"Useless : Trying to check IS [NOT] NULL on the field " + field.getSQLElementType().getName() + "#"
|
||||||
+ field.name + " which is declared in the ORM as 'can't be null'");
|
+ field.getName() + " which is declared in the ORM as 'can't be null'");
|
||||||
fild = field;
|
fild = field;
|
||||||
nulll = isNull;
|
nulll = isNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<String, List<Object>> toSQL() {
|
public Pair<String, List<Object>> toSQL() {
|
||||||
return new Pair<>(fild.name + " IS" + ((nulll) ? " NULL" : " NOT NULL"), new ArrayList<>());
|
return new Pair<>(fild.getName() + ((nulll) ? " IS NULL" : " IS NOT NULL"), new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user