Which Java ORM support not-typesave modification of object?
I want to modify objects / records in a generic way, where the fieldName is a string input parameter, and value is a generic AnyObject parameter. Do you know something like this?
I.e. in Core Data in iOS it can work like this:
I went though ormlite tutorial and I just realized, need to get the appropriate Dao, to insert an item:
This is exactly how ActiveJDBC works. Check out at http://javalite.io.
Related
Synopsis: I'm trying to create an SQL update using jOOQ
DSL.using(connection)
.update(DSL.table("dogs"))
.set(DSL.field("age"), DSL.field("age").add(1))
.set(DSL.field("rabies"), "true")
.where(DSL.field("id").eq("Kujo"))
.execute();
Issue:
The method set(Field<Object>, Object) is ambiguous for the type UpdateSetFirstStep<Record>
Question: How do I create this update using jOOQ?
You ran into this problem: Reference is ambiguous with generics
Fixing your query
It's always a good idea to attach data types with your jOOQ expressions. In your particular case, you can work around the problem by specifying things like:
DSL.field("age", SQLDataType.INTEGER)
Or, shorter, with the usual static imports:
field("age", INTEGER)
Using the code generator
However, jOOQ is best used with its code generator, see also this article here. Not only will you avoid problems like these, but you also get compile time type safety (of data types and meta data), advanced features like implicit joins and much more.
Your query would then look like this:
DSL.using(connection)
.update(DOGS)
.set(DOGS.AGE, DOGS.AGE.add(1))
.set(DOGS.RABIES, true)
.where(DOGS.ID.eq("Kujo"))
.execute();
I'm currently evaluating JOOQ because I believe I started reinventing the wheel which looks very close to part of JOOQ :)
Now, while digging in great JOOQ documentation I've found that my use case lies somewhere between Using JOOQ as SQL Builder and Using JOOQ as SQL Builder with Code generation i.e. I would like to:
Create plain SQL strings like it is shown in Using JOOQ as SQL Builder part
Instead of using hard-coded DSL.fieldByName("BOOK","TITLE") constructs, I prefer storing name of a table along with it's column names and types like it's shown in Using JOOQ as SQL Builder with Code generation part
I prefer not to use code generation (at least not on regular basis), but rather creating TableImpl myself when new table is needed.
While digging in manual, I've found how table implementation should look like in chapter Generated tables. However, TableImpl class as well as Table interface should be parameterized with record type and the same goes for TableField class. I believe this is done for easier type inference when directly querying database and retrieving results, though I may be mistaken.
So my questions are:
Is there a guide in manual on how to create Table and TableField implementations? Or I can simply generate them once for my database schema and use generated code as a guideline?
How can I gracefully "discard" record type parameters in implemented classes? First, I thought about using java.lang.Void class as type parameter but then I noticed that only subclasses of Record are allowed... The reason is that I don't need record types at all because I plan to use generated by JOOQ SQL queries in something like Spring JdbcTemplate so mapping is done by myself.
Thanks in advance for any help!
Given your use-case, I'm not sure why you'd like to roll your own Table and TableField implementations rather than using the ones generated by jOOQ. As you stated yourself, you don't have to regenerate that code every time the DB schema changes. Many users will just generate the schema once in a while and then put the generated artefacts under version control. This will help you keep track of newly added changes.
To answer your questions:
Yes, there are some examples around the use of CustomTable. You may also find some people sharing similar experiences on the user group
Yes you can just use Record. Your minimal custom table type would then be:
class X extends TableImpl<Record> {
public X() {
super("x");
}
}
Note that you will be using jOOQ's internal API (TableImpl), which is not officially supported. While I'm positive that it'll work, it might break in the future, e.g. as the super constructor signature might change.
For example, I have a JSON format like this:
{"class":"MySpecialClass", "attri1":"value1", "attri2":"value2"}
I would like to create a Object, which is a MySpecialClass Object, and get two attribute, attri1 and attri2 with the value of value1 and value2.
Here is the requirement:
I have a class file, named, MySpecialClass, and have attri1, and attri2, can I create this object, and assign the value in this?
I DONT'T have the class file MySpecialClass, I would like to generate it on the runtime, is this possible to do so? Thanks.
Your first case is perfectly feasible using any Java/JSON parser.
Your second case is possible, but hard work.
You can construct classes at runtime using bytecode engineering - e.g. using Apache BCEL. Note that the JSON will contail fields only, and not behaviour nor type.
Take a look at https://github.com/google/gson it does what you want
You want a JSON processor, like Jackson. I'm not sure you can easily do your second case this way, for that you may be best looking at a JVM JavaScript implementation unless you want to get into stuff like on the fly bytecode manipulation. There's one in the Java6 runtime.
I'm developing a Scala extension to an existing Java ORM (Ebean). The goal of this project is to add as much type safety as possible to the ORM.
Instead of
Ebean.find(Product.class).fetch("name", "unit").findList()
I would finally like to be able to write something like
(objects of entity[Product] with attributes name and unit) getIt
(note that this is just a very first DSL approach).
The ORM model is already defined as
#Entity
public class {
public String name;
public String unit;
}
In order to achieve type safety at compile time for the attributes in the query, I would need to access them on e.g. a dummy object like (new Product()).name.
I think this is the best way to ensure that only such model members are used that exists on that class, but, at runtime, I need a way to recognize that this variable was accessed. Otherwise I would just call that member name and wouldn't know about this in my query.
Does anybody know a way how to achieve this? Is there a possibility to trace when a variable is accessed and to give that information, at runtime, to any other object?
I already thought about hooking into getters and setters instead of using public members in the model classes, but this would either make the query or the model very ugly. Another problem is that any additional specific methods would have to be added manually for each model.
I would be happy if anyone could suggest possible solutions. Thanks!
If you are willing to define the fields of your model objects as something like the Record Fields, what Emil suggested could work, but if you're building your solution on top of a Java ORM using custom types might be an issue. If you need to track field access I think your best bet will be runtime bytecode instrumentation using a library like CGLib or Javassist. You can pass an instrumented "dummy" object into the body of your function, then track which field was accessed in a thread local. That's how it's done in Squeryl.
You could take a gander at how the Lift folks have implemented Mapper and Records. It allows for type safe queries using companion objects (as well as using raw sql). It does require inheriting traits into your model and the fields are specified as objects and not regular vals. Might be helpfull though. You can find the source for the persistance stuff here.
I work with a dynamic Dataset model, which (in short) takes in attributes and stores them in a Map like this...
Dataset dataset = new Dataset();
dataset.setAttribute("name", "value");
...for later recovery, like this...
String value = dataset.getAttribute("name");
...and that has worked wonderfully for my purposes. But now I'm in a place where I'd like to use a templating engine to dynamically generate HTML. In the template, it's not ideal for me to do a lot of ${dataset.getAttribute("name")}. It would be rather nice if I could create artificial methods whenever something was added to a Dataset. For instance, if I did this...
dataset.setAttribute("name", "value");
...I'd like to be able to retrieve it like this...
String name;
name = dataset.name;
//or
name = dataset.getName();
...but so far I haven't been able to pull it off. What approach might I take here? Is it even doable?
Edit:
I understand that Velocity offers Property Lookup Rules to try to resolve dataset.name to dataset.get("name"), and that's great, but I need to know how to achieve this in the case that Velocity isn't the target as well.
See http://velocity.apache.org/engine/releases/velocity-1.5/user-guide.html#propertylookuprules
If your method was named get(String attribute) rather than getAttribute(String attribute), you could use the same syntax as for regular properties. So, either refactor your class, or add an additional get method that does the same thing as getAttribute, or transform your object into a Map, which has a get method.
In the past I have generated POJOs dynamically with Objectweb's ASM. This has the benefit that the underlying fields are type safe and much more efficient (esp for privative values)
You can use Dynamic Spring proxies with AOP technology or CGLib proxies. AOP could be used to describe getters like this : execution(public * com.bla.YourClass.get*())")
From what I've seen, it's fairly common for template engines for Java to support both
getters/setters of the form getAttribute, and
implementation of the Map interface
Before you spend too much time looking for a more generic solution (assuming the above won't be supported like it is in Velocity), it's probably worth taking a look at the other engines to see if any of them don't support it. If all your possible targets do, then you're probably fine relying on it.
I'm a big fan of making sure you actually have a problem before you spend the time to solve it.