hernan silberman

Greenhorn
+ Follow
since Nov 20, 2001
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
0
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by hernan silberman

Just in case it's useful for others, I ended up doing the following when each client starts up:

1) Create a temporary queue and consumer to receive a response on.
2) Send a request message to a well known request queue asking for the current "menu" object. This request message includes the name of the temporary response queue in a string property.
3) Do a blocking consumer.read() on the temporary response queue.
4) Delete the temporary queue.
5) Subscribe to a topic to receive updates to the "menu" object.

This was pretty easy to do and the resulting code is simple. Let me know if you have any improvements spot any potential issues with this approach.

thanks...
hernan
I'm working on a system where applications receive notifications each time an important shared object's state changes. This object is like the menu at a restaurant--whenever it changes all of the restaurant employees receive a new message with the updated menu they should use from that point forward.

What I'd like to do is send them the most recent message as soon as they subscribe to the topic with the latest version of the menu so that I don't have to provide it to them by other means or equip them to find it on their own.

I'm sort of new to JMS--let me know if there's a standard mechanism or practice for doing this. At this time I'm planning on having each client send a request message to a dedicated queue when they start up and then wait until they receive the initial object on a separate response queue to simulate a synchronous request/response.

thanks...
Hernan
Well, in the example I came up with above the class represents an immutable class. No set methods, everything is passed in through the constructor and does not change.

Making the members final when they can be gives me some assurance that a maintenance programmer won't try to reassign them in the future--at least not without (hopefully) thinking about it as they delete the final keyword.

It's not critical, but I like to use the compiler as a shield whenever I can.

hernan
I have another comment and request for the iBatis developers. I've been working on lots of new code and I start by designing the Java classes I would prefer to work with and support. They usually look like this:



If I need to persist this class to iBatis, I end up having to make lots of concessions and it looks like this (using latest version 2.2):



* Fields are no longer final.
* Had to add a public constructor.
* Had to add a private setter for Data1 (but I'm happy it can be private in 2.2)
* Had to lose the Collections.unmodifiableList() wrapper on my getter for the List<Somethings>

(I'm new to iBatis so I may have missed something, please feel free to point those out).

Anyhow, I'm not a super-picky but I wish I didn't have to think so hard about persistence when I write my Java code. I know there's work in progress to help make this better with iBatis, so consider this an additional "yes, please"!

thanks...
hernan
[ December 07, 2006: Message edited by: Bear Bibeault ]
Another one for Clinton, Brandon & Larry,

I've been really enjoying the new Java 5 features lately and I'm amazed at how they've improved various open source toolkits. JUnit especially--the new annotations are simply amazing and make test driven development easy (and fun!).

I've seen Spring and Hibernate take advantage of annotations and generics and I'm wondering if there are plans to use these in iBatis. I can see how iBatis might leverage generics, though I'm not sure how much that would buy me since I don't mind casting what iBatis queries give me to List<MyType>.

I'm wondering what the plans are for annotations which seem to have really suped up Junit, Spring and Hibernate, and possibly other Java 5 features, if any.

thnx...
Hernan
Hi Clinton, Brandon & Larry. Glad to have you here! All of the "* In Action" books I've read have been great and I look forward to reading yours.

I've been learning iBatis over the past few weeks and I've noticed that the .NET and Java implementations differ in various ways. I can understand that they will be necessarily different in some ways, but some really great features--like the ability to use constructors to build objects from result sets--seem to exist in the .NET version but not yet in the Java version (v2.2). What's the plan for bringing this great feature to the Java version and for preserving parity across iBatis implementations in general?

I'm also curious how you approach this in your book--do you cover both the .NET and Java (and even the Ruby) implementations?

thnx...
Hernan
I think you're best off depending on the Level 2 cache, instead of reusing the Session cache. I would recommend this very common approach:

1) Use a connection pool. This way you don't end up doing the heavy lifting to rebuild a new connection for each request you get.

2) Select and use the Level 2 cache. Read up on the details of how to do this properly, the Hibernate documentation is really strong on this topic.

3) Once you have read the documentation, you will understand how to properly query your Hibernate entities so that Hibernate checks the Level 2 cache before assembling your objects from scratch from the database.

hope this helps...
Hernan
You're using Query.list() in your code:

contacts = q.list();

If you want to take advantage of the Level 2 cache, use Query.iterate() instead. You should carefully read the hibernate documentation to fully understand the level 2 cache and how it works.

hernan
If you're using criteria queries, you can do like the Hibernate manual says here:

---------------------
There are quite a range of built-in criterion types (Expression subclasses), but one that is especially useful lets you specify SQL directly.

List cats = sess.createCriteria(Cat.class)
.add( Expression.sql("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) )
.list();
---------------------

Otherwise, you can use a native SQL query in Hibernate, which is really useful for cases where you have vendor-specific SQL to use, such as a rule hint for your optimizer:

-------------------
13.1. Creating a SQL based Query

SQL queries are exposed through the same Query interface, just like ordinary HQL queries. The only difference is the use of Session.createSQLQuery().

Query sqlQuery = sess.createSQLQuery("select {cat.*} from cats {cat}", "cat", Cat.class);
sqlQuery.setMaxResults(50);
List cats = sqlQuery.list();
-------------------

Here's a link to the full Hibernate docs, I think what you're looking for is in Chapter 13:

http://www.hibernate.org/hib_docs/reference/en/html_single/

hernan
I work on a small enterprise application which handles about 300 concurrent users. The server is all Java, uses Spring, Hibernate, Oracle and is accessed mostly through a rich client Java application but also via web services (for C++/Perl/Python integration). The server runs on a single Linux system.

We recently started using a Level 2 cache with Hibernate and things work great once certain objects have had their state cached. We have a couple of UI table views in our rich client which display a dense collection of information representing a large portion of our domain object model graph. Loading these UI views when the data they display is not in the cache is unacceptably slow, but once the data is cached it takes just a blink.

We've settled on a strategy with a cache loader which runs as soon as the application server is started. It does several simple HQL queries like "from SomeEntity where .." to get the important common data cached as part of startup. This cache loading takes a while, about 8-10 minutes.

The performance boost we've achieved by tuning our way to this strategy has impressed our users quite a bit, which is why we're sticking to it for now. Before Hibernate and the Level 2 cache came into the picture, these views were built from complicated SQL queries which were as tuned as we and our very talented DBA could get them. The new setup with the L2 cache is many times faster than these SQL queries, plus it feels more scalable since Oracle isn't being consulted as often.

Still, I can't help but feel like I took an application that started up quickly and had a small footprint and turned it into one that starts up slowly and uses lots of memory. It performs better, the tradeoff seems completely worth it, but I feel like a bad engineer each time I have to wait for the server to start. Cognitive dissonance.

Are any of you doing this sort of caching on startup? I've been looking around to get a sense of how common this practice is.

Thanks for listening,
h
Thanks, I had already seen the Fluffy Cat cart and I wasn't too impressed with it. It's advertised as "Unfinished" and I was hoping for something more sophisticated and in wider use. Please let me know if you know of any others!

thanks...
Hernan
I'm tasked with building a web application that includes (among other things) shopping cart functionality with all of the usual bells and whistles. It occurs to me that this is probably the most common application built by web application programmers and I was hoping to avoid building yet another one of my own.

I have found many non-commercial open source PHP and Perl shopping cart systems and I was hoping to find some open source implementations in Java. So far, I haven't had much luck.

I'd be interested to know if you've had a good experience with a quality open source shopping cart system written in Java, or if (as I suspect)
everyone just rolls their own as needed.

many thanks...

Hernan Silberman
San Francisco
We ran into this same problem. Instead of disabling lazy loading or otherwise crippling our Domain Object Model to make those objects work in a client/server environment, we decided to build code to send "value objects" (aka transfer objects) to the client instead of the domain objects. This adds complexity to your architecture, but it's worthwhile to study your use cases to determine if modifying your domain objects or building code to construct transfer objects makes more sense for your application.

Here's a simple example of how you might automate the building of transfer objects. Beware that this is an oversimplified example, but a worthwhile read (3 part article):
http://www.javaranch.com/newsletter/July2003/newsletterjuly2003.jsp#a5

Here's a discussion about the Transfer Object pattern:
http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html

Here's a sourceforge project for building transfer objects, though I haven't used it before:
http://xsnapshot.sourceforge.net/

thanks...
hernan

You can use multiple strategies for this: use a hierarchy of classes the upper level containing only the directly fetched info (no relations). Another option where using DTOs is to involve some JavaBean mapping tools (BeanUtils for example).



In our case, using BeanUtils proved to be the most flexible option. This allowed us to have a very nice Domain Object Model on the server that we could tune in fine fashion and also gave us the flexibility to decide exactly what collection of data, from exactly which domain objects, needed to be sent to a client for them to successfully complete a use case. This is the power of data transfer objects.

The highly connected objects in a typical Domain Object Model generally make poor data transfer objects, they're designed with different goals. Using class inheritance to separate autofetch/lazy fetch class attributes is interesting, but seems like a strange reason to subclass.

This is really an application-specific issue, and I can imagine some projects where serialized DOM instances would work fine. I have to imagine that the typical enterprise application would benefit from thinking carefully about Data Transfer Objects.

More on the topic:
http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html

hernan
I'm working on a project using Hibernate and our biggest technical hurdle was building code to construct Data Transfer Objects based on one or more of our mapped Domain Object Model classes. Both JDO and Hibernate claim that this simply isn't necessary because you can "detach" persistent instances and they become your DTOs or value objects. This is true in theory, but has proven ugly in practice:

* Detatched JDO instances are instrumented by the JDO compiler. Code on the client side might call a public method that accesses a lazy unitialized collection and all hell breaks loose. You could defend against this problem by forcing all lazy references to load, but you might end up with a massive object graph, if your schema and mappings are good. Plus, you have to include jdo.jar on the client (ugly).

* Detatched Hibernate instances have the same problem, except they're instrumented at runtime. Again, you could defend against this problem by forcing all lazy references to load, but you might end up with a massive object graph, if your schema and mappings are good. Plus, you have to include hibernateX.jar on the client (ugly).

* The API on our DOM instances were rarely the APIs we wanted to expose on the client side. Data hiding was important and it confuses developers to have a public API they're not supposed to use on the client side. Plus, this couples the client and the server too much. We became squeamish when we realized how much responsibility we were putting into a single class. Often in our object model, a DTO was built using pieces of several domain objects.

Anyhow, it was clear fairly early that we had to use DTOs on our project and that this is a design decision everyone will have to make for themselves. Overall, our experience with both Hibernate and JDO have been extremely positive. I just thought I'd point out that both JDO (Solarmetric) and Hibernate docs are a bit overly-positive about not needing to build special code for DTOs. This is common sense for a seasoned application developer: DTOs/value objects are still an important pattern to understand, even with Hibernate or JDO.

thanks...
Hernan