tapestry extending start example

Posted in hibernate, java, java ee, jpa, spring, spring framework, tapestry5, web framework tagi , , , , , , , on listopad 5, 2009 by eyemirror

lets examine starting tutorial from tapestry

creating project

http://tapestry.apache.org/tapestry5/tutorial1/first.html

mvn archetype:create
-DarchetypeGroupId=org.apache.tapestry
-DarchetypeArtifactId=quickstart
-DgroupId=org.apache.tapestry
-DartifactId=tutorial1
-DpackageName=org.apache.tapestry5.tutorial

when I typed command my maven shell printed nice error message saying that something went wrong and it gives up. but the command below will work and will create all nice preconfigured project for us

mvn archetype:generate
-DarchetypeCatalog=http:/</tapestry.formos.com/maven-snapshot-repository
-DarchetypeGroupId=org.apache.tapestry
-DarchetypeArtifactId=quickstart
-DgroupId=my.package
-DartifactId=mywebapp

the other way round would be creating simple maven web project and then editing pom file to get all necessary libraries.

If you want pretty printing for framework exception messages add

...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.0.2</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
                <optimize>true</optimize>
                <encoding>${project.build.sourceEncoding}</encoding>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>maven-jetty-plugin</artifactId>
            <version>6.1.9</version>
            <configuration>
                <!-- Log to the console. -->
                <requestLog implementation="org.mortbay.jetty.NCSARequestLog">
                    <!-- This doesn't do anything for Jetty, but is a workaround for a Maven bug
                         that prevents the requestLog from being set. -->
                    <append>true</append>
                </requestLog>
            </configuration>
        </plugin>
    </plugins>
  ...
</build>
<strong><reporting>
    <!-- Adds a report detailing the components, mixins and base classes defined by this module. -->
    <plugins>
        <plugin>
            <groupId>org.apache.tapestry</groupId>
            <artifactId>tapestry-component-report</artifactId>
            <version>${tapestry-release-version}</version>
            <configuration>
                <rootPackage>info.kamiseq</rootPackage>
            </configuration>
        </plugin>
    </plugins>
</reporting></strong>
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

tapestry and hibernate

http://tapestry.apache.org/tapestry5/tutorial1/forms2.html
I couldn’t force my project to work with db through hibernate. I had huge problems with tapestry-hibernate lib. so I switched to spring and configured hibernate as a JPA’s vendor. Anyway you don’t need that either, to finish the tutorial just create simple dao object that will hold HashMap of Address object to hold created with site addresses.

tapestry and IOC

tapestry works with Inversion of Control framework of its own. So there is no need to use external framework like spring inject you custom objects in simple app. to configure IOC you need create (unless there is one) AppModule in your.package.services package and add

public static void bind(ServiceBinder binder){
    binder.bind(AddressDAO.class, AddressRdmsDao.class);
}

then you can use @Inject with your interface like any other service (bean)

@Injectprivate AddressDAO dao;

extending the tutorial’s example

I added row parameter to the grid (in Index.tml) so I could add action links and customizing grid’s content but then I wished to had action link that will show item in the grid in t:beandisplay component. ok let’s go..

in Index.java

@Property
@Persist
private Address address;
@Inject
private BeanModelSource beanModelSource;
@Injectprivate ComponentResources resources;
//this will control grid's display model but it can be done with add/reorder/include paramateres in the tml
public BeanModel<Address> getAddressModel() {
    BeanModel<Address> model = beanModelSource.createDisplayModel(Address.class, resources.getMessages());
    model.add("action", null);
    return model;
}
//to handle show action
Object onActionFromShow(Long id) {
    this.address = this.dao.find(id);
    return this;
}

in Index.tml

<t:grid source="addresses" row="address" model="addressModel"
    reorder="honorific, firstName, lastName, email, phone, street1, street2, city, zip, country, action"
    add="show">
    <t:parameter name="actionCell">
        <t:pagelink page="address/create" t:context="address.id">update</t:pagelink>
    </t:parameter>
    <t:parameter name="showCell">
        <t:actionLink t:id="show" t:context="address.id">show</t:actionLink>
    </t:parameter>
    <p:empty>
        <p>Brak danych, wprowadź addresata - <t:pagelink page="address/create">dodaj</t:pagelink>.</p>
    </p:empty>
</t:grid>
<ul>
    <li><t:pagelink page="address/create">Create new address</t:pagelink></li>
</ul>

ok so we have show action that will set address reference to wanted object. but if we put t:beandisplay component below t:grid then we will see the last object processed by grid (as the grid and beandisplay uses the same property address). So to see the address we clicked on then wee need to use different name for property or swap grid and display components places, is there any other way??????.

<t:if test="address">
    <t:beandisplay object="address">
    </t:beandisplay>
</t:if>
<t:grid source="addresses" row="address" model="addressModel"
        reorder="honorific, firstName, lastName, email, phone, street1, street2, city, zip, country, action"
        add="show">
    <t:parameter name="actionCell">
        <t:pagelink page="address/create" t:context="address.id">update</t:pagelink>
    </t:parameter>
    <t:parameter name="showCell">
        <t:actionLink t:id="show" t:context="address.id">show</t:actionLink>
    </t:parameter>
    <p:empty>
      <p>Brak danych, wprowadź addresata - <t:pagelink page="address/create">dodaj</t:pagelink>.</p>
    </p:empty>
</t:grid>
<ul>
    <li><t:pagelink page="address/create">Create new address</t:pagelink></li>
</ul>

and finally surround t:beandisplay with t:if to test existance of address object

Flex + cairngorm

Posted in flex tagi , , , , on luty 3, 2008 by eyemirror

O.K. before we will go any further, here are some useful links

  1. 6 articles under http://www.adobe.com/devnet/flex/articles/ pt1, pt2, pt3, pt4, pt5, pt6. Although all of those are quite old (from the beginning of 2006) can be a good starting point if you have no flex, flash, design patterns background.
  2. Saying truth I’ve found them a bit dull, so I’ve looked for some better live examples like here or here. Nothing really special about them but are showing how you can put pieces together.

Yes, I agree that flex allows us to create impressive views really fast just putting components on the form. But view is not an application or rather simple application. If we decide to change anything, add some sophisticated way to call a server, sort items in lists, manage states – it can take the same time as to write new application.

It seems cairngorm (I hate this name:) framework (CF for simplicity) provides all of classes to develop scalable application. It puts pressure on MVC&S (model, view, controller and service ), Command, Mediator design patterns, so why not just use it. The other thing is that CF is supported by Adobe, so I think it is a good choice.

limitations of Hibernate

Posted in Java Persistence API, hibernate, java, java ee, jpa, remoting tagi , , , , , , , , , , , on styczeń 19, 2008 by eyemirror

Serialization issue

I have found that my Hibernate’s entities are working fine only when I am using them locally by jsp-es or servlets.

Unfortunately my goal was to connect thick client to server. That time I was using flex 3 to build client and AMF3 protocol with weborb to invoke remote methods on my Spring’s beans. The problem I run into was that I used lazy initialization in entities and while serializing LazyInitializationException is thrown. It is natural as I object is outside the transaction and something is getting data from entity.

It seems that it can be solved,

  1. by using OSIV filter(open session in view) – but really I don’t know if serialization will not fetch lazy initialized collections.
  2. by using custom object-queries to return a simple object or collection of objects rather than entity (look to JPA specification).
  3. by mapping entities with Dozer framework – in my opinion, it is not really promising for more complicated entities relationships with lazy, eager combinations.

I don’t have too much time now, so check it by yourself.

Fortunately for me I switch to java desktop application and there I can use spring’s HttpInvoker.

Extending entity issue

When creating hierarchy of entities that are stored in the same DB table, you need to be careful with relationships between them. I don’t know why, but Hibernate is not always using @DiscriminatorColumn flag to filter data set and that is violating Collection type.

Take care.

extended example

Posted in Java Persistence API, hibernate, java ee tagi , , , , , , on styczeń 19, 2008 by eyemirror

The good news is, finally I mapped my model using Hibernate’s entities that perfectly fits to my DB model. Only this time I started with creating db tables and then force Hibernate to persist data to right table in right way.

But normally I should think in terms of object and relationships they have and don’t care about backstage operations. The thing is Hiberante is not optimal, and you cannot expect that it is very fast. Hibernate is a good tool to make something quick, without spending hours or days to write all value objects and sql queries.

UML diagrams
uml model

Entities

  1. here is the zip file with chosen entities from my project (not all of them). To unzip the file use the password ‘djshadow‘ :) hell yeah (I am using 7zip softwear)
  2. customer entity is a base class for all concern, owner, service and integrator classes. each concern can be owner as well and each integrator can be service. There is a ManyToMany relationship between service and station split into 2 OneToMany relationships that is holding additional filed for that relationship

//TODO
get reed of relationship annotations and move them to xml file where they can be changed easily without recompiling classes.

mapping objects

Posted in Java Persistence API, java, java ee, jpa on grudzień 23, 2007 by eyemirror

ok lets discuss how object can be persist and retrieve
at least two things need to be taken under account writing your entities

  1. direction in relationships – take a look. And a good example showing relations between objects http://java.boot.by/scbcd5-guide/ch05s04.html. Notice how each relation is mapped to DB.And something interesting about hibernate, thing I was so confused about. (I’ve took it form one of polish google group so If you are interested in whole post go to http://groups.google.com/group/pl.comp.lang.java/brows)
    “Transparent POJO-oriented persistence implementations such as Hibernate do not implement managed associations. Contrary to CMR, Hibernate associations are all inherently unidirectional.”

    following the author, Hibernate is not too clever and can’t figure out that objects are related in both way, we should assign them manualy, and he is advising simple code like this

    @Entity
    class Company {
    ...
            public void addEmployee(Employee empl) {
                    getEmployees().add(empl);
                    empl.setCompany(this);
    
            }
    }
  2. fetching style – lazy or eager – defined in your
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)

    annotation. Main difference is when collection of your related entity is created. One important thing to remember is that each fetch operation is within transaction. After that transaction success and your fetch type is lazy, you can’t get collection of related objects. One solution is to fetch with eager type but this makes a lot of sql selects to your DB and you use more memory for your objects. It doesn’t matter for 1000 records in your DB but over 10000 it can make a difference.

    As far as I’m concerned better way is to lazy fetch and then use em.merge(object) method on object that is currently outside transaction. the method will set all related collection.

simple entity example

Posted in Java Persistence API, java, java ee, jpa on grudzień 23, 2007 by eyemirror

Take a look how easy entities can be created, it is just a simple example but that was my intention.

package pl.mypck.db;

import ...;

@Entity
@NamedQueries({
    @NamedQuery(name = "Book.fetchAuthor", query = "SELECT b FROM Book b WHERE b.author = :author"),
    @NamedQuery(name = "Book.fetchAllBooks", query = "SELECT b FROM Book b")
})
public class Book implements Serializable {
    private static final long serialVersionUID = 1L;
    private Long id;
    private String author;
    private List<Page> pages = new ArrayList();

    public void setId(Long id){this.id = id;}
    public void setAuthor(String a){this.author = a;}
    public void setPages(List<Page> ps){this.pages = ps;}
    public void addPages(Page p){this.pages.add(p);}
    @Id
    @SequenceGenerator(name="BOOK_SEQ", allocationSize=0, sequenceName="BOOK_SEQ")
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="BOOK_SEQ")
    @Column(name="id_book")
    public Long getId() {
        return id;
    }
    public String getAuthor(){return this.author;}
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    /* when bidirectional mapping */
    //with bidirectional mapping I should add mappedBy="book" to @OneToMany annotation
    public List<Page> getPages(){
        return this.pages;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Book)) {
            return false;
        }
        Book other = (Book) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return " pl.mypck.db.Book[id=" + id + "]";
    }
}
//Page class
package pl.mypck.db;

import ...;

@Entity
public class Page implements Serializable {
    private static final long serialVersionUID = 1L;
    private Long id;
    //private Book book; /* when bidirectional mapping */
    private String content;

    public void setId(Long id){this.id = id;}
    //public void setBook(Book b){this.book = b;}/* when bidirectional mapping */
    public void setContent(String c){this.content = c;}

    @Id
    @SequenceGenerator(name="PAGE_SEQ", allocationSize=0, sequenceName="PAGE_SEQ")
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="PAGE_SEQ")
    public Long getId() {return id;}
    //@ManyToOne(cascade={CascadeType.ALL})/* when bidirectional mapping */
    //@JoinColumn(name="id_book")/* when bidirectional mapping */
    //public Tabela getBook() {return this.book;}/* when bidirectional mapping */
    public String getContent(){return this.content;}

    /*
     *
     */
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Page)) {
            return false;
        }
        Page other = (Page) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "pl.mypck.db.Page[id=" + id + "]";
    }
}

so now we have two classes (entities) that we can use as normal objects and will be saved in some DB. here only Book knows about its pages (aka indirect mapping).

Page p = new Page();
p.setContent("text on first page");
Book b = new Book();
b.addPages(p);

it is working, fetching and inserting or updating, deleting but what Hibernate created in DB system is stunning.

about Jpa (Java Persistence API)

Posted in Java Persistence API, hibernate, java, java ee, jpa on grudzień 23, 2007 by eyemirror

a good starting point

the good thing about using JPA is that we can work with different vendors like Hibernate or TopLink underneath, without focusing on specific implementation. In another words we have next layer of abstraction of accessing data.

Main benefits of using JPA are:

  • thinking in terms of objects
  • quick implementation of data model
  • no need to care about DB tables implementation
  • for simple mappings you have everything ready to work
  • no need to implement mappers to and from object to your db

Disadvantages are:

  • SQL queries are not that optimized (like everything that is for general use). So if you need something fast think about using something different.
  • frameworks (like Hibernate) are not that intelligent as you could expect.
  • when your model gets complex, you need to write queries anyway to retrieve objects

Of course there are some possibilities to overcome problems I’ve mention above.
Good enough to start, check related topics.

configuring Tomcat and spring framework

Posted in Tomcat, java, java ee, spring, spring framework on grudzień 23, 2007 by eyemirror

add this to your web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/classes/springConfig.xml</param-value>
    </context-param>
    <listener>
        <description>domyslny listener dla sF</description>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
..
..
</web-app>

ok and now prepare your spring xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
        <property name="driverClassName" value="org.postgresql.Driver"/>
        <property name="url" value="jdbc:postgresql://localhost:5432/dbname"/>
        <property name="password" value="pass"/>
        <property name="username" value="user"/>
        <property name="poolPreparedStatements"><value>true</value></property>
        <property name="maxActive"><value>10</value></property>
        <property name="maxIdle"><value>10</value></property>
    </bean>
    <bean id="injectionTest" class="pl.mypck.InjectionTest">
        <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>

read more in spring documentation about IoC and beans http://static.springframework.org/spring/docs/2.5

where to start

Posted in java, java ee on grudzień 22, 2007 by eyemirror

good to read

download first

  • http://www.springframework.org/
  • http://tomcat.apache.org/ – if you want to use tomcat with some IDE like netbeans or eclipse, download zip package instead of win-installer as it doesn’t have start-up and stopping file with it. win installer is using services to start and stop server.
  • http://www.netbeans.org/ – ready to use. 6th version is OK. I had impression that it has problems with deploying my war files on server.
  • http://www.eclipse.org/downloads/ – heh for inexperienced user as I am it was and sometimes it is a nightmare to configure it. or maybe I had just a bad luck.

purpose

Posted in Uncategorized on grudzień 22, 2007 by eyemirror

recently I ve started my adventure in enterprise solutions from sun. still I have a lot to learn but I want to have a place where I could put some examples how I solve problems.

I hope my blog will help someone trying familiarize with j2ee, the way you have helped me.