Upcom.eu Blog

May 13, 2009

Update multiple svn repositories from single project

Filed under: subversion — Tags: , , , — kflokos @ 6:31 am

Recently, we came across the requirement to develop using our own subversion repository, while updating the client’s repository every time an iteration completed and delivered.

Our initial thoughts were pretty much pessimistic, with doubtful merges and lots of manual work. Fortunately the following worked without any problem:

Create two working directories:

  • the master one, linked to the internal svn repository. All development takes place in that working directory. Assume that the connect string is something like svn+ssh://user@server/svn/repo1. If necessary do a checkout from that repository: svn co svn+ssh://user@server/svn/repo1
  • the client one, linked to the client’s svn repository. Assume that the connect string is something like svn+ssh://clientUser@clientServer/var/svn/clientRepo1. Perform a checkout the first time to make sure the repository location is properly set: svn co svn+shh://clientUser@clientServer/var/svn/clientRepo1

At the end of an iteration, commit all the changes from developers working on this iteration. It is assumed that this would be the version delivered to the client for further testing.

Now move to the client’s directory and perform an export from the internal repository, using the following operation: svn exp svn+ssh://user@server/svn/repo1. That will bring the latest version of the internal repository to the working directory linked to the client repository. Then, just by performing a simple check in we update the client’s repository with the latest change: svn ci.

The above process works well only in case the client is not performing changes to the repository simultaneously with your team!If this is not the case, more work is required to get those changes back to the master repository!

It may also be used for occasional snapshots of the master repository to guarantee against its potential failures.

January 19, 2009

Improving Hibernate performance using second level cache

Filed under: Hibernate — Tags: , , — Nikolaos Konstantinou @ 11:20 am

There is a trick that pays off when there are ResultSets or entities in a web application that are not updated so often: second-level caching. Getting second-level cache to work means that entities or
ResultSets can be stored in the cache and not retrieved from the database in future calls.

There are many cache providers, among them is EhCache which we will be using in this example. In order to get second-level cache to work, first we have to tell hibernate about it. Add this in the hibernate configuration file (hibernate.cfg.xml):

<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="cache.use_query_cache">true</property>
<property name="cache.use_second_level_cache">true</property>
These properties tell hibernate that we will be using EhCache for entity and query caching. Then, create a file named ehcache.xml (the default name of the EhCache configuration file) and put it in the same location with hibernate.cfg.xml, typically in the classpath root. A sample configuration for ehcache.xml is the following:

<ehcache>
<diskStore path="java.io.tmpdir"/>

<defaultCache
maxElementsInMemory="20000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="300"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="300"
memoryStoreEvictionPolicy="LRU" />

<cache name="com.app.entities.City"
maxElementsInMemory="15000"
eternal="true"
overflowToDisk="false" />
...
</ehcache>

In short, this tells EhCache to use the java temp folder and to store a maximum of 20000 entities in the cache (cities for instance). The configuration for each entity overrides the global configuration in the ehcache.xml file. In this example, the global setting defines a TimeToLiveSeconds value which is overriden for the City entities, causing them to be stored eternally in the cache. The same holds for the cache location: global configuration allows the usage of the hard disk but for the entities cached, only the memory will be used (overflowToDisk=false).

But, what happens when an entity changes? There is no problem as long as the entity is configured through hibernate:

@Entity
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class City {
private Long id;
private String name;
....
}

The @Cache annotation in this example uses a READ_WRITE strategy, which tells hibernate to update the cache when the entity is updated. If the entity is not so probable to be changed, a read-only strategy will suffice (CacheConcurrencyStrategy.READ_ONLY).

The good part is that ResultSets can be stored as well. Suppose you have a query that returns the most popular cities by country. Define it as cacheable and it will be evaluated against the database only once:

public List<City> findPopularCitiesByCountryId(Long countryId) {
List<City> cities = session.createQuery("FROM City AS c WHERE
c.country.id=? ORDER BY c.popularity DESC")
.setCacheable(true)
.setLong(0, countryId)
.setMaxResults(20)
.list();
return cities;
}

The trick is the setCacheable property of the query. Running the application in debug mode, you will see in the output for the first time

[net.sf.ehcache.Cache]-[DEBUG] org.hibernate.cache.StandardQueryCache cache - Miss
[org.hibernate.cache.StandardQueryCache]-[DEBUG] query results were not found in cache

[org.hibernate.cache.ReadWriteCache]-[DEBUG] Cache miss: com.app.entities.City#1412
[org.hibernate.event.def.DefaultLoadEventListener]-[DEBUG] object not resolved in any cache

…but in subsequent calls you will be happy to see, that even if the query cache fails:

[net.sf.ehcache.Cache]-[DEBUG] org.hibernate.cache.UpdateTimestampsCache cache - Miss
[org.hibernate.cache.EhCache]-[DEBUG] Element for cities is null

the entities will be retrieved from the cache:

[org.hibernate.cache.ReadWriteCache]-[DEBUG] Cache lookup: com.app.entities.City#1412
[org.hibernate.cache.ReadWriteCache]-[DEBUG] Cache hit: com.app.entities.City#1412

There you go, you just boosted your application’s performance. Take care though, common sense orders that you should only cache ResultSets or entities that are frequently accessed and rarely modified. You can find more info at the official hibernate manual:
http://www.hibernate.org/hib_docs/v3/reference/en/html/performance.html

January 12, 2009

Multiple LDAP servers

Filed under: LDAP — Tags: , , , — kflokos @ 8:54 pm

I’ve been struggling to make spring ldap work with multiple LDAP servers (for fail over and load balancing reasons). Reading was working properly – even though it seems like the second server was never used! Even though strange, I thought it was only used when the first one was down – no load balancing.

The biggest problem was writing. Novell eDirectory complained with the error error result (50); NDS error: no access (-672); Insufficient access. Specifying just one server always worked, with the same admin user connected!

The problem drove me crazy, until I found out that the “urls” parameter of the org.springframework.ldap.core.support.LdapContextSource takes as parameters a String array and not a single String where the LDAP connection parameters are separated with space (another post on the Internet suggested that). The correct configuration is then something like the following:


<bean id="contextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="urls" value="${ldap.url1},${ldap.url2}" />
<property name="base" value="${ldap.base}" />
<property name="userDn" value="${ldap.userDn}" />
<property name="password" value="${ldap.password}" />
<property name="pooled" value="false"/>
<property name="baseEnvironmentProperties">
<map>
<entry key="com.sun.jndi.ldap.connect.timeout" value="${ldap.timeout}" />
<entry key="com.sun.jndi.ldap.read.timeout" value="${ldap.timeout}" />
</map>
</property>
</bean>

If, instead of comma(,) in the urls property you separate the entries with a space, updates (at least) do not work!

November 25, 2008

Multiple View Criterias. One Result.

Filed under: ADF, Jdeveloper 11g — Tags: , , — Stassinopoulos Dimitris @ 5:19 pm

Here is a Hint of how to take advantage of ADF and ViewCriterias.

There are cases that users demand to have more than QueryCriterias for a specific page; There is also the case to have those QueryCriterias in different tabs and disclose the desired one and have a conjunction of both in the result form or table at the same time. This functionality could be desired in many cases and sometimes could not be avoidable.

Some cases when the criteria attributes are too many to fit in one page, or if the user will want to reset some of the attributes and not all, then, you need to use two or even more PanelQuery components to produce one joined query.

In ADF this means to create more than one ViewCriterias in the viewObject.

But, I faced the problem of applying all those view criterias as a one combined query. The result was not filtering from all view criterias but the one disclosed.

At first my mind went on partial triggers, messing with iterators etc, but the solution was much quicker and more elegant.

Follow the steps described below into your application and see the results

  1. Go to your ViewObject and create the Java Implementation class

  2. Inside the class Override the executeQuery() method.

  3. Place the following code:

@Override

public void executeQuery() {

//get all view criteria names

String[] allViewCriterias=this.getAllViewCriteriaNames();

// apply them as one joined Criteria

this.setApplyJoinedViewCriteriaNames(allViewCriterias);

//now execute query.

super.executeQuery();

}

That’s it!

Now you can have as many ViewCriterias as you want and have one joined Query.

The method is called every time you press search button no matter in which Panel Query you are on and you can reset some attributes and not all.

Older Posts »

Powered by WordPress