Over a million developers have joined DZone.

Typesafe Property Literals in Database Queries or Data Binding

· Database Zone

To stay on top of the changing nature of the data connectivity world and to help enterprises navigate these changes, download this whitepaper from Progress Data Direct that explores the results of the 2016 Data Connectivity Outlook survey.

In short: we generate typesafe property literals with lombok to help us write database queries and data binding. It’s fun.

I hardly know any language that supports property and method literals. Class literals are properly supported in Java, and are useful in many cases. Field or property literals can also enable us write good frameworks The Hibernate Criteria API for example uses the Metamodel generator to create literals that can be used for type-safe query building.

We also found it handy to have these literals, so we created lombok-ds, a fork of lombok-pg to automatically create these literals for us. In case you don’t know project lombok, check it out, it’s fun and helps a lot!

Generally, our lombok version creates a static “_property” field for the properties of your java class that reflects their name and type, and can also be used to get and set the value of that property on a given instance.

There’s a good idea of typesafe querying without generated metadata in Java 8, explained here: http://benjiweber.co.uk/blog/2013/12/28/typesafe-database-interaction-with-java-8/. For those who can’t wait for Java 8, these generated property literals can be a better option. It also does not rely on reflection, so it can also be used with GWT.

Note that Joda Beans (http://www.joda.org/joda-beans/) is also a similar framework, and for those who cannot use lombok on their project, it can be a good choice.

Usage Examples

An example of a database query:

ds.query(Entity.class)
    .filterAttribute(Entity._stringAttribute)
    .valueEquals(“hello world”)
    .select().getAll();

An example of a value binding:

textBox.bind(model()
    .get(Model._person)
    .get(Person._age)
    .convert(new IntegerStringConverter()));

JSF value binding:

Value bindings can also be used in JSF. I wrote an article earlier (http://java.dzone.com/articles/creating-jsf-pages-pure-java ) on how we create JSF views from Java code. It’s even more useful if the EL expressions can be written type-safely, with compile-time checking. With these attribute literals, it’s easy and straightforward.

We are not currently planning to release our query builder, but we I will soon introduce our data binding solution, that will also be released as open source in a few weeks.

How to use it

To get the source, go to https://github.com/Doctusoft/ds-bean  and https://github.com/Doctusoft/lombok-ds . The binaries are not currently in any public repo, so you have to build it from the sources. Lombok-ds inherited an ant build, so you have to install the binary manually to your repository.

The dependencies are:

<dependency>
    <groupId>com.doctusoft</groupId>
    <artifactId>ds-bean</artifactId>
    <version>0.1.4</version>
</dependency>
<dependency>
    <groupId>com.doctusoft</groupId>
    <artifactId>lombok-ds</artifactId>
    <version>0.1.4</version>
</dependency>

To use it in eclipse, you have to run lombok-ds-0.1.4.jar and specify your eclipse installation directory. To use it with GWT, you have to add -javaagent:web-inf/lib/lombok-ds-0.1.4.jar=ECJ as a JVM parameter to the run configuration and to the GWT compiler. You can find further information about this in the lombok docs.

How it works

The Attribute interface is quite simple:

public interface Attribute<Holder, Value> {
    Value getValue( Holder instance );
    void setValue( Holder instance, Value value );
    Class<Holder> getParent();
    Class<Value> getType();
    String getName();
}

The name can be used well in building database queries, class instances are returned for runtime type checking and reflection, and the getter and setter methods can be used for entity mapping or value binding. And whatever you need them for.

We found that once you have these literals, they just turn out to be useful in many cases.

Our lombok fork creates the necessary code. This class for example:

public class Example {
    @Attribute
    private String value;
}

Will be expanded transparently, compile-time as:

public class Example {
    private String value;
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    private static final Attribute<Example, String> _value = new Attribute<Example, String>() {
        @Override
        public void setValue(Example instance, String value) {
            instance.setValue(value);
        }
        @Override
        public String getValue(Example instance) {
            return instance.getValue();
        }
        @Override
        public Class<String> getType() {
             return String.class;
        }
        @Override
        public Class<Example> getParent() {
            return Example.class;
        }
        @Override
        public String getName() {
             return "value";
	}
    };
}

Note that the getters and setters are also automatically generated. If you are working with Eclipse or Netbeans, these generated methods and fields will be visible instantly for content assist and outline.

Let us know in what other cases you find these literals useful!

Turn Data Into a Powerful Asset, Not an Obstacle with Democratize Your Data, a Progress Data Direct whitepaper that explains how to provide data access for your users anywhere, anytime and from any source.

Topics:

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}