I want to add sorting to a HTML table populated by Hibernate. The actual sorting has to be done by a database. To feed "Order by" condition to the database Java has to match passed sort parameters to a column in a query. I'm unsure how to implement this matching.
I could pass something like "Employee.salary" but then this condition need to be checked like all parameters passed from client. This check would require getting column name from Hibernate annotations, and this is not easy I guess. Also, the column can be query-specific and not corresponding to a table field.
Another way is to use hardcoded values in a presentation layer. But this will tie presentation layer with a persistence layer, which is also not good I think.
How do you deal with server-side sorting in web applications?
You have to create some kind of an intermediate layer that maps the column names between the view and the tables. This way you can send extra parameters to your query in an encapsulated form, and in your server side code you can use them according to your actual query.
For sorting do sth like this:
public class ColumnMapping {
String tableColName;
String dbColName;
//getters, setters, ctors and anything else required
}
List<ColumnMapping > orderColumns = new ArrayList<ColumnMapping >();
orderColumns.add(new ColumnMapping("foo", "bar"));
//... server side
StringBuilder queryString = new StringBuilder("select * from books ");
if(orderingApplicable) {
queryString.appendd("order by ");
queryString.append(implode(orderColumns, ", "));
}
Where implode is a theoretical function gluing the list elements with commas into a string.
Remarks:
You can easily pre-populate the view-db mapping on startup if immutable.
The same can be done for group by.
This is just a stub, but extensible to include aggregate functions or whatever you need
If I have an Employee entity, then I want an EmployeeRepository that lets me findEmployeesBySalary(SortType sortType, int skip, int limit)
From the web service side, I want a URI like
foo.com/employees?by=salary&skip=10&limit=50
which returns something like (as a AJAX XHR call)
<employees>
<employee uri="/employee/1" />
<employee uri="/employee/2" />
<employee uri="/employee/3" />
</employees>
or the full-blown HTML page rendered appropriate.
This conveniently allows caching of employees on the client side (which the cache size being flexible) and at the HTTP level.
Note that, column names? Irrelevant. You would have a HiberateEmployeeRepository that implements the EmployeeRepository interface as needed. Express this stuff as methods, and use complex parameters if you need to.
You could even have two separate methods if you want, rather than an enum, findHighestPaidEmployees and findLowestPaidEmployees - foo.com/employees?salary=lowest&skip=10&take=30 mind you, that's a horribly depressing URI.
You could sort data at the client side, with help various js tools. It will be minimize requests to database
Related
I'm on a project that uses the latest Spring+Hibernate for persistence and for implementing a REST API.
The different tables in the database contain lots of records which are in turn pretty big as well. So, I've created a lot of DAOs to retrieve different levels of detail and their accompanying DTOs.
For example, if I have some Employee table in the database that contains tons of information about each employee. And if I know that any client using my application would benefit greatly from retrieving different levels of detail of an Employee entity (instead of being bombarded by the entire entity every time), what I've been doing so far is something like this:
class EmployeeL1DetailsDto
{
String id;
String firstName;
String lastName;
}
class EmployeeL2DetailsDto extends EmployeeL1DetailsDto
{
Position position;
Department department;
PhoneNumber workPhoneNumber;
Address workAddress;
}
class EmployeeL3DetailsDto extends EmployeeL2DetailsDto
{
int yearsOfService;
PhoneNumber homePhoneNumber;
Address homeAddress;
BidDecimal salary;
}
And So on...
Here you see that I've divided the Employee information into different levels of detail.
The accompanying DAO would look something like this:
class EmployeeDao
{
...
public List<EmployeeL1DetailsDto> getEmployeeL1Detail()
{
...
// uses a criteria-select query to retrieve only L1 columns
return list;
}
public List<EmployeeL2DetailsDto> getEmployeeL2Detail()
{
...
// uses a criteria-select query to retrieve only L1+L2 columns
return list;
}
public List<EmployeeL3DetailsDto> getEmployeeL3Detail()
{
...
// uses a criteria-select query to retrieve only L1+L2+L3 columns
return list;
}
.
.
.
// And so on
}
I've been using hibernate's aliasToBean() to auto-map the retrieved Entities into the DTOs. Still, I feel the amount of boiler-plate in the process as a whole (all the DTOs, DAO methods, URL parameters for the level of detail wanted, etc.) are a bit worrying and make me think there might be a cleaner approach to this.
So, my question is: Is there a better pattern to follow to retrieve different levels of detail from a persisted entity?
I'm pretty new to Spring and Hibernate, so feel free to point anything that is considered basic knowledge that you think I'm not aware of.
Thanks!
I would go with as little different queries as possible. I would rather make associations lazy in my mappings, and then let them be initialized on demand with appropriate Hibernate fetch strategies.
I think that there is nothing wrong in having multiple different DTO classes per one business model entity, and that they often make the code more readable and maintainable.
However, if the number of DTO classes tends to explode, then I would make a balance between readability (maintainability) and performance.
For example, if a DTO field is not used in a context, I would leave it as null or fill it in anyway if that is really not expensive. Then if it is null, you could instruct your object marshaller to exclude null fields when producing REST service response (JSON, XML, etc) if it really bothers the service consumer. Or, if you are filling it in, then it's always welcome later when you add new features in the application and it starts being used in a context.
You will have to define in one way or another the different granularity versions. You can try to have subobjects that are not loaded/set to null (as recommended in other answers), but it can easily get quite awkward, since you will start to structure your data by security concerns and not by domain model.
So doing it with individual classes is after all not such a bad approach.
You might want to have it more dynamic (maybe because you want to extend even your data model on db side with more data).
If that's the case you might want to move the definition out from code to some configurations (could even be dynamic at runtime). This will of course require a dynamic data model also on Java side, like using a hashmap (see here on how to do that). You gain thereby a dynamic data model, but loose the type safety (at least to a certain extend). In other languages that probably would feel natural but in Java it's less common.
It would now be up to your HQL to define on how you want to populate your object.
The path you want to take depends now a lot on the context, how your object will get used
Another approach is to use only domain objects at Dao level, and define the needed subsets of information as DTO for each usage. Then convert the Employee entity to each DTO's using the Generic DTO converter, as I have used lately in my professional Spring activities. MIT-licenced module is available at Maven repository artifact dtoconverter .
and further info and user guidance at author's Wiki:
http://ratamaa.fi/trac/dtoconverter
Quickest idea you get from the example page there:
Happy hunting...
Blaze-Persistence Entity Views have been created for exactly such a use case. You define the DTO structure as interface or abstract class and have mappings to your entity's attributes. When querying, you just pass in the class and the library will take care of generating an optimized query for the projection.
Here a quick example
#EntityView(Cat.class)
public interface CatView {
#IdMapping("id")
Integer getId();
String getName();
}
CatView is the DTO definition and here comes the querying part
CriteriaBuilder<Cat> cb = criteriaBuilderFactory.create(entityManager, Cat.class);
cb.from(Cat.class, "theCat")
.where("father").isNotNull()
.where("mother").isNotNull();
EntityViewSetting<CatView, CriteriaBuilder<CatView>> setting = EntityViewSetting.create(CatView.class);
List<CatView> list = entityViewManager
.applySetting(setting, cb)
.getResultList();
Note that the essential part is that the EntityViewSetting has the CatView type which is applied onto an existing query. The generated JPQL/HQL is optimized for the CatView i.e. it only selects(and joins!) what it really needs.
SELECT
theCat.id,
theCat.name
FROM
Cat theCat
WHERE theCat.father IS NOT NULL
AND theCat.mother IS NOT NULL
I'm trying to figure out how to select a list of objects as part of a Hibernate group-by query. I know how to do it a harder way, but I'm curious if there is some special sugar syntax that achieves the same thing.
Basically, I have a query of this structure:
select com.myapp.domain.TagSummary(
tag.id, tag.term, tag.description, tag.synonyms, count(user)
)
from User user
join user.tags tag
I'd like to store the tag.synonyms as a List<Tag>. Is that possible, or do I need to query the cross product and do the separation manually after the query results come back?
Alternatively, what I really want in the end is a list of synonym terms separated by commas. So if a tag is spring and it has synonym terms spring-framework and spring-framework-3.1, it would be great to put into the constructor the string spring-framework, spring-framework-3.1. Is that possible?
EDIT: I have learned that I can use group_concat() to achieve the second half of the functionality, but it's only available in MySQL. Is there a way to make it available in hsqldb as well? In Spring 3.1, how do I add this function to Hibernate? I know I should call something on Configuration, but I don't know what bean to access it by.
for (Object[]> result : query.list()) {
Tag tag = (Tag ) result[3];
User user = (User) result[4];
}
You can get more information from this link
https://derrickpetzold.com/p/in-and-group-by-count-hibernate/
Although appengine already is schema-less, there still need to define the entities that needed to be stored into the Datastore through the Datanucleus persistence layer. So I am thinking of a way to get around this; by having a layer that will store Key-value at runtime, instead of compile-time Entities.
The way this is done with Redis is by creating a key like this:
private static final String USER_ID_FORMAT = "user:id:%s";
private static final String USER_NAME_FORMAT = "user:name:%s";
From the docs Redis types are: String, Linked-list, Set, Sorted set. I am not sure if there's more.
As for the GAE datastore is concerned a String "Key" and a "Value" have to be the entity that will be stored.
Like:
public class KeyValue {
private String key;
private Value value; // value can be a String, Linked-list, Set or Sorted set etc.
// Code omitted
}
The justification of this scheme is rooted to the Restful access to the datastore (that is provided by Datanucleus-api-rest)
Using this rest api, to persist a object or entity:
POST http://datanucleus.appspot.com/dn/guestbook.Greeting
{"author":null,
"class":"guestbook.Greeting",
"content":"test insert",
"date":1239213923232}
The problem with this approach is that in order to persist a Entity the actual class needs to be defined at compile time; unlike with the idea of having a key-value store mechanism we can simplify the method call:
POST http://datanucleus.appspot.com/dn/org.myframework.KeyValue
{ "class":"org.myframework.KeyValue"
"key":"user:id:johnsmith;followers",
"value":"the_list",
}
Passing a single string as "value" is fairly easy, I can use JSON array for list, set or sorted list. The real question would be how to actually persist different types of data passed into the interface. Should there be multiple KeyValue entities each representing the basic types it support: KeyValueString? KeyValueList? etc.
Looks like you're using a JSON based REST API, so why not just store Value as a JSON string?
You do not need to use the Datanucleus layer, or any of the other fine ORM layers (like Twig or Objectify). Those are optional, and are all based on the low-level API. If I interpret what you are saying properly, perhaps it already has the functionality that you want. See: https://developers.google.com/appengine/docs/java/datastore/entities
Datanucleus is a specific framework that runs on top of GAE. You can however access the database at a lower, less structured, more key/value-like level - the low-level API. That's the lowest level you can access directly.
BTW, the low-level-"GAE datastore" internally runs on 6 global Google Megastore tables, which in turn are hosted on the Google Big Table database system.
Saving JSON as a String works fine. But you will need ways to retrieve your objects other than by ID. That is, you need a way to index your data to support any kind of useful query on it.
I have one search widget where people search for car dealers by zip code. There are also some optional checkboxes to refine search in that widget.
Here is the URI for searching dealer by zip code.
http://localhost:8080/dealer/zip/10080
If user selects checboxes then the URI will be
http://localhost:8080/dealer/zip/10080servicetype=type1&servicetype=type2&servicetype=type3
I am using jersey. Here is java code.
#Path("/dealer")
#Produces(MediaType.APPLICATION_JSON)
public class DealerLocatorRS {
private DealerService dealerService=new DealerService();
#GET
#Path("/zip/{zip}")
public List<Dealer> getByZip(#PathParam("zip") String zip,
#QueryParam("servicetype") List<String> servicetype){
.. . ..
}
Is this right approach to pass optional and multiple values and . Can anybody help me to apply best practices?
I'm not sure that I'd map a search for dealers in a particular zip code to a resource; it doesn't feel quite right. Instead, I'd have a resource that lists all the dealers, with individual dealers being sub-resources of that. If it was possible to return a subset of the list of subresources restricted by properties (e.g., their zip code) then that would be a great way to implement a search, otherwise I'd have a separate search handler that returns a list of links to matching dealer resources.
#Path("/dealer")
public class Dealers {
#GET
public List<Dealer> getAll() { ... }
#GET
#Path("search/byZip")
public List<URI> getByZip(#QueryParam("zip") String zip, ...) { ... }
#Path("{dealerId:[^/]+}")
public Dealer getDealer(#PathParam("dealerId") String id) { ... }
}
If you are serious about understanding and applying REST, I'd recommend reading the REST paper, if you haven't done so yet.
According to the architecture proposed in that paper, Each URL maps to a resource.
A resource could be something extrinsic and tangible, like a car dealership. Or it could be something "virtual" like a "region", or even a zipcode that might contain dealerships.
As to how you parameterize queries, think about what resource you want to use to satisfy or expose the queries. Why would you treat "zipcode" as a variable parameter, any differently than, say your "servicetype"? Are they not both qualifiers to select a subset of dealerships? Think about why you are making them different - there may be a good reason.
For example, you could do:
http://server/dealer/zip/10070
list all dealers in 10070
http://server/dealer/service/transmissions
list all dealers that do transmission work
http://server/dealer/service/transmissions/zip/10070
list all dealers that do transmission work in zip 10070
http://server/dealer/zip/10070/service/transmissions
list all dealers in zip 10070 that do transmission work
http://server/dealer/service/transmissions/service/lighttrucks
list all dealers that do transmission work and do light truck service
Think about the mapping of URLs to resources. It may be that two distinct URLs map to the same "result". you need to decide whether that's appropriate for you.
It's also perfectly fine to retrieve a resource and then do queries on it on the client side. Not all work need be done by the server. You could search through the results obtained by http://server/dealer/zip/10070 on the client side, to find the ones that supply the desired services. This may or may not be a performance win, depending on the size of the data transmitted and the frequency and variety of queries.
Supposing an overall result set of 10 (say, ten dealers within a zipcode), a Javascript foreach loop searching for a dealer that offers service X is going to be faster than an additional AJAX call asking the server to do that query on behalf of the client.
This is ok, unless your URL becomes too long (although URL length is not limited by any spec, some browsers and intermediaries limit it, so the best practices to keep it under 1K)
If it becomes too long, you may use POST instead of GET.
P.S. You have bug in your code, it should be #QueryParam("servicetype") List<String> servicetype) to match the example URI.
The Facts
I have the following datastructure consisting of a table and a list of attributes (simplified):
class Table {
List<Attribute> m_attributes;
}
abstract class Attribute {}
class LongAttribute extends Attribute {}
class StringAttribute extends Attribute {}
class DateAttribute extends Attribute {}
...
Now I want to do different actions with this datastructure:
print it in XML notation
print it in textual form
create an SQL insert statement
create an SQL update statement
initialize it from a SQL result set
First Try
My first attempt was to put all these functionality inside the Attribute, but then the Attribute was overloaded with very different responsibilities.
Alternative
It feels like a visitor pattern could do the job very well instead, but on the other side it looks like overkill for this simple structure.
Question
What's the most elegant way to solve this?
I would look at using a combination of JAXB and Hibernate.
JAXB will let you marshall and unmarshall from XML. By default, properties are converted to elements with the same name as the property, but that can be controlled via #XmlElement and #XmlAttribute annotations.
Hibernate (or JPA) are the standard ways of moving data objects to and from a database.
The Command pattern comes to mind, or a small variation of it.
You have a bunch of classes, each of which is specialized to do a certain thing with your data class. You can keep these classes in a hashmap or some other structure where an external choice can pick one for execution. To do your thing, you call the selected Command's execute() method with your data as an argument.
Edit: Elaboration.
At the bottom level, you need to do something with each attribute of a data row.
This indeed sounds like a case for the Visitor pattern: Visitor simulates a double
dispatch operation, insofar as you are able to combine a variable "victim" object
with a variable "operation" encapsulated in a method.
Your attributes all want to be xml-ed, text-ed, insert-ed updat-ed and initializ-ed.
So you end up with a matrix of 5 x 3 classes to do each of these 5 operations
to each of 3 attribute types. The rest of the machinery of the visitor pattern
will traverse your list of attributes for you and apply the correct visitor for
the operation you chose in the right way for each attribute.
Writing 15 classes plus interface(s) does sound a little heavy. You can do this
and have a very general and flexible solution. On the other hand, in the time
you've spent thinking about a solution, you could have hacked together the code
to it for the currently known structure and crossed your fingers that the shape
of your classes won't change too much too often.
Where I thought of the command pattern was for choosing among a variety of similar
operations. If the operation to be performed came in as a String, perhaps in a
script or configuration file or such, you could then have a mapping from
"xml" -> XmlifierCommand
"text" -> TextPrinterCommand
"serial" -> SerializerCommand
...where each of those Commands would then fire up the appropriate Visitor to do
the job. But as the operation is more likely to be determined in code, you probably
don't need this.
I dunno why you'd store stuff in a database yourself these days instead of just using hibernate, but here's my call:
LongAttribute, DateAttribute, StringAttribute,… all have different internals (i.e. fields specific to them not present in Attribute class), so you cannot create one generic method to serialize them all. Now XML, SQL and plain text all have different properties when serializing to them. There's really no way you can avoid writing O(#subclasses of Attribute #output formats)* different methods of serializing.
Visitor is not a bad pattern for serializing. True, it's a bit overkill if used on non-recursive structures, but a random programmer reading your code will immediately grasp what it is doing.
Now for deserialization (from XML to object, from SQL to object) you need a Factory.
One more hint, for SQL update you probably want to have something that takes old version of the object, new version of the object and creates update query only on the difference between them.
In the end, I used the visitor pattern. Now looking back, it was a good choice.