-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Properties with underscores in names are not found #3
Comments
That sounds weird and is definitely something that should be supported. Do you have a matching constructor or a default constructor and public field/setter for the field? Can you post a minimal failing example (class and call to the query)? What version of Dalesbred are you using? Anyway, it seems that at least I need to improve the error messages. |
that's all code actually try {
postgres = Database.forDataSource(DataSourceFactory.getDataSourceFromProperties("db-bi"));
List<Location> rows = postgres.findAll(Location.class, Location.prototype.findAll(false));
} catch (Exception e) {
logger.fatal(e.toString());
e.printStackTrace();
} that's model public class Location extends Model {
public static final Model prototype = Model.getPrototype(MethodHandles.lookup().lookupClass());
public Integer loc_id;
// public Integer parent_id;
// public Double longitude;
// public Double latitude;
// public Integer level;
// public Date created;
// public Date input_time;
// public Integer is_point;
public String title;
@Override
public String tableName() {
return "locations";
}
@Override
public String primaryKeyName() {
return "loc_id";
}
} and at DB side (postgres), loc_id is int4 |
and my base Model class is a wrapper without properties or getters/setters. just with some additional default methods like 'primaryKeyName()', 'tableName()' and etc. |
abstract public class Model<T> {
private static final Map<Class<?>, Object> prototypesCache = new ConcurrentHashMap<>();
private static final Map<Class<?>, ArrayList<String>> attributesCache = new ConcurrentHashMap<>();
private static final Map<Class<?>, ArrayList<Field>> fieldsCache = new ConcurrentHashMap<>();
/**
* Create, cache and return singleton for provided class
* @param type
* @return Model
*/
static synchronized protected Model getPrototype(Class type) {
if (type == null || type.getSuperclass() != Model.class) {
throw new NullPointerException("Type is null or not subclass of " + Model.class.getSimpleName());
}
Object model = null;
if(!(prototypesCache.containsKey(type))) {
try {
model = type.newInstance();
prototypesCache.put(type, model);
} catch (Exception ignored) {
throw new NullPointerException("Can't create singleton for " + Model.class.getSimpleName());
}
} else {
model = prototypesCache.get(type);
}
return (Model)model;
}
protected synchronized ArrayList<Field> fields() {
Class cls = this.getClass();
if(fieldsCache.containsKey(cls))
return fieldsCache.get(cls);
ArrayList<Field> fields = new ArrayList<>();
try {
for (Field f : cls.getDeclaredFields()) {
if(!(Modifier.isStatic(f.getModifiers()))) {
fields.add(f);
}
}
} catch(Exception ignored) {
}
fieldsCache.put(cls, fields);
return fields;
}
/**
* Return list of attributes for model
* @return ArrayList<String>
*/
public synchronized ArrayList<String> attributeNames() {
Class cls = this.getClass();
if(attributesCache.containsKey(cls))
return attributesCache.get(cls);
ArrayList<String> attributes = new ArrayList<>();
try {
attributes.addAll(fields().stream().map(Field::getName).collect(Collectors.toList()));
} catch(Exception ignored) {
}
attributesCache.put(cls, attributes);
return attributes;
}
/**
* Return name of table
* @return String
*/
public String tableName() {
return this.getClass().getSimpleName().toLowerCase();
}
/**
* Return name of primary key
* @return String
*/
public String primaryKeyName() {
if (!(this.attributeNames().contains("id"))) {
throw new NullPointerException("There is no primary key with name ID. You must override primaryKeyName() for that model.");
}
return "id";
}
/**
* return SQL query to get list of all models
* @return String
*/
public String findAll(String field, boolean sort) {
String sql = "SELECT " + StringUtils.join(this.attributeNames(), ",") + " FROM " + this.tableName();
if(sort)
sql += " ORDER BY " + field + " ASC";
System.out.println(sql);
return sql;
}
public String findAll(boolean sort) {
return findAll(this.primaryKeyName(), sort);
}
public String findAll() {
return findAll(false);
}
} |
i'm not very pro at java, just few days, but for me looks like nothing exceptional here. At least other models with another connection (to Oracle) works fine. Only Postgres with all these int4, int8 failed :( |
version is: |
The problem is actually very simple: your property in Java is named So just rename the property to That said, the error message should have been more informative. And actually there's no reason for Dalesbred to enforce not having underscores in Java properties. It's not normal style, but if you want or need them, Dalesbred should still find the property. So I'm leaving this issue open and will improve the property-resolution algorithm for next version so that it would have find your |
at db side field named as loc_id. i see solution for right now (strip underscore at Java side), but it would be better to allow to use underscore. i would like to stick the same names as at db. |
hmmm...actually at my current way of usage it does not help :( because i'm trying to build query from public properties of model :( if i remove underscore, than final sql would be corrupted :( |
Well, your SQL-generation code could convert But I will fix this in a future version anyway. |
yep, finally i came to same solution as you advice - just used your StringUtils. As tempo solutions it's enough (i wrote a really simple 'query builder' with using your StringUtils). |
if at DB side i have int4/int8 and at Model side i have Integer, than DefaultInstantiatorRegistry can't instantiate the class. Postgres.
The text was updated successfully, but these errors were encountered: