Detailed Howto
Content
Known Limitation
Description of what you will get
Installation of necessary Software
Configuration
Create the Hibernate part
Build the jar File to feed the Wicketizer
Appendix
Known Limitation
Do not use Columnname id! Microsofts Internet Explorer is not updating fields with name id via Ajax- Wicketizer uses the db columnname as caption in all tiers.
If you use only Firefox, you do not have any problem even with columns with name id.
Additionaly the Primary key has to be of type Number / Integer.
Everything is tested with latest Java 6 only (Java 5 might work, 1.4.2 will not work)!
Description of what you will get
... just some Highlights
Functional View
For each Entity (Table/View) you will get two Pages: One whichuses Ajax heavily and one which uses it mostly not.
Each Page(Ajax or not) consists of a Listpanel and and Editpanel
The Menu
All Pages are reachable to an Ajax menu. The Menu can be adapted and provide many Levels (I have tested to 5 hierarchy levels by now - but I am not aware of a limitation of Levels) in the Baseclass.
The Listpanel
... gives you a list of all entries you have (30 Entities per page as default). You can Filter your Entities by the embedded Filterpanel, for shrinking the List by providing Filter Criteria. You can select an Entry in the list via Link - that Entry will be displayed in Editpanel.
The Editpanel
... will give you CRUD operations for the current Entity. Validation can be included in many cases wiht one additioal line of code
Security
... can be changed in Parent Class of Wicket Applications (MBOApp), by default all Pages are in Security Context (see WicketPage for changing that).
Technical View:
just as an insight ....
Model
... is a LoadableDetachable Model (see Wicket Examples for details)which is embedded in other Models (either Model or Compoundmodel).
That reduces Memory usage significantly: Only Identifier and nonpersistent Data (like Filtercriteria, no of sublist /amount of Sublists for PagebyPage, ...) will be hold in Memory, at the end of the request cycle all other data will be persisted).
Page by Page
... is realized by a class I call DataViewport. It will select (via hibernate - a little tricky:-) only a sublist of 30 items and will hold the current sublist number and the max of Sublists. It further has methods to check if the current position is the first or the last and if there is a previous sublist or a next sublist (this position Data is not persisted in LoadableDetachableModel. That call is only done on READ -that differs from default behaviour of LoadableDetachable Models which loads multiple time per Request ...).
DAO
You will get a DAO (using HQL) per Entity.
Jetty
... is embedded to provide a simple start.
Installation of necessary Software
Download and install Eclipse
You can eihter use Yoxos to configure your Eclipse or do it on your own.
Alternative one: Yoxos
Goto http://www.yoxos.com/geteclipse/start
Click in the left window in the Package explorer on the "+ Web and Java EE Development" then on "+JBoss Tools" , then select "Hibernate Tools".
In the Middle in the upper "Schedule" Tab is a green Arrow (Hint is "Add the selected features to the Schedule" - press that.
Now a confirmation Dialog will come up and show you the dependencies that are there.
Press "OK" (you can add further Plugins as you need). Press Button StartDownload in the Schedule Panel.
You will get a preconfigured complete Eclipse. - just extract it and it is usable (noproblems with updates or Dependencies ... for me it just works).
Alternative two: Enhance Eclipse manually
Goto http://www.eclipse.org/downloads/ and download the Eclipse IDE for Java EE Developers (min SR2))
.
Extract it and start it.
Goto Help --> Software Updates ... --> Select Tab Available Software--> Press Button Add Site and enter http://download.jboss.org/jbosstools/updates/stable/ , say ok
Select Hibernate Tools (under JBoss Tools Development ... -->JBoss Tools 3.0...).
Database
... select a database of your choice and install it.
I use H2- that is Database at its best: high performance, easiest setup,maintenance easy, fast support , ... (thank you, Thomas Müller!).
If I really think h2 might be to small (more as 4GB data and growing fast) I recommend postgresql.
Installation, start / stop as well as maintenance of Database is OUT OF SCOPE.
However to simly start with h2, you only have to download it and add the bin/h2.jar to your Eclipse Projects Buildpath.
Start Eclipse and create a new Java Project (File -> New-> Procject-> Java > Java Project)
Add also your Database Driver to your Project:
- Rightclick in Package Explorer on your Project, -> Properties -> Libraries ->add external JARs
- Navigate the jar from your database vendor (e.g. h2.jar) select it and press OK.
Install hibernate
Update (not needed with latest hibernate Tools version later than April 2009)
Download hibernate core from Hibernate and extract it.
In Eclipse rightclick on your project, select properties, select Java BuildPath,
- Rightclick in Package Explorer on your Project, -> Properties -> Libraries ->add external JARs
- Navigate to the folder to which you downloaded and extracted hibernate
- add hibernate.jar
Install hibernate-annotations
Download and extract hibernate-annotations form Hibernate.
In Eclipse rightclick on your project, select properties, select Java Build Path, select add external jars and select all jars from where you have extracted the hibernate annotations to.
- Rightclick in Package Explorer on your Project, -> Properties -> Libraries ->add external JARs
- Navigate to the folder to which you downloaded and extracted hibernate-annotation
- add ejb3-persistence.jar, hibernate-annotations.jar, hibernate-commons-annotations.jar and hibernate-core.jar.
By this you can use annotations in your project (otherwise your annotated java classes would have a lot of errors).
Configuration
Configuration of Hibernate perspective
First You should build your hibernate.cfg.xml and place it in src folder of your project. For h2 it would be like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="whatever">
<property name="hibernate.connection.driver_class">org.h2.Driver</property>
<property name="hibernate.connection.username">rain</property>
<property name="hibernate.connection.password">man</property>
<property name="hibernate.connection.url">jdbc:h2:~/wicketizer/dbfile</property>
<property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
<property name="hibernate.show_sql">false</property>
<property name="hibernate.hbm2ddl.auto">update</property>
</session-factory>
</hibernate-configuration>
(adapt it accordingly)
In Project you creaded under Database switch to Hibernate Perspective (Window-> Open Perspective-> Hibernate)
- Rightclick under Hibernate (left site, where in Java Perspective usually the Package Explorer is shown) on the white.
- Select Add Configuration
- Provide a Name (e.g Wicketizer, or whatever you like)
- Select Type as Annotations jdk1.5 +
- Select your project with the browse button
- Select Database Connection as Hibernate Configured Connection (only in latest version available)
- Ignore the property file
- Goto Configuration File's Setup button.
It will ask if a new or an existing file should be used. Choose existing one and select the one you have build one step earlier.
Hints:
The hibernate.show_sql has values true|false. If true, all communication between hibernate and database will logged out (sometimes very helpful, but a real performance Killer).
The hibernate.hbm2ddl.auto has as parameter none|update|create. None is default and nothing will happen, update will update Hibernate mappings accordingly and create will create a new database accordingly and will drop the existing one!!!
If you plan to use a schema with hibernate.hbm2ddl (by adding 'schema ="schemaname" ' in the java file), this schema has to be generated before the tabels will be created in that schema!!!
Create the Hibernate part
Wicketizer needs a jar file, which will hold the annotated java files and the hibernate.cfg.xml file (see Structure of jarFile above):
It is not mandatory to create the Tables in the database - that can be done via Hibernate on the fly. You have to create annotated java classes and hibernate.cfg.xml manually in that case.
If you are familiar with Databases, just create your Database as usual and generate from DB.
Alternative one - start with Database
This is recommend for Starters in both (e.g. U. Fligg or M. Paggen:-) as well as Gods of databases (e.g. W. Vonnemann) .
Build your prefered DB as usual. Test it and WHEN IT IS READY carry on.
Start Eclipse and use the Project you created above (hibernate and Database Dirver in Buildpath).
Goto Hibernate Perspective
Click on checkbox arrow on the right site of the symbol right from Run Last Tool (green arrow with hibernate sign at bottom) and select "Hibernate Code Generation Configurations ..."
- Provide a name for your configuration e.g myhibgenconfig
- Select your Console configuration (use arrow)
- Specify output dir to $PROJECTNAME/src (use Browse button )
- Check "Reverse engineer form JDBC Connection
- Specify your package structure (e.g. org.wicketizer.hib)
Goto Tab Exporters
- Check Use Java5 Code
- Check Generate EJB3 Annotations
- Check Domain Code (.java)
- Hibernate XML Configuration(cfg.xml)
press apply and run.
After that you should have a all annotated java Class files in the package you have given above... .
Rework
Make sure that you import only javax.persistance for
- Column
- Id
- ManyToOne
- OneToMany
- Table
Therefore check the import statements of your generated java classes (if not, remove all import statements, press ctrl + shift + o and select now the proper ones)
Alternative two - start with Hibernate (generate the Database)
If you are familiar with hibernate, you can create the annotated java beans on your own and the hibernate.cfg.xml.
DO NOTUSE HashSet - Wicketizer by now assumes Lists to be used. It will not crash, but it will not work out of the box.
However you should test your work by asking hibernate to create the DB for you - and test it (1:n or n:m correct? what about primary keys ....).
If you are done, than you can generate the database. Therefore set the following line for hibernate.hbm2ddl.auto in your hibernate.cfg.xml
- <property name="hibernate.hbm2ddl.auto">create</property>
Have in mind that your database will be created from scratch (and be empty) if the value of hibernate.hbm2ddl.auto is create (change to update) after creation.
It might help to use a different location for your database (if you use H2, creation is done on the fly).
Hint:
IMHO Alternative one is easier to start, but for adoptions Alternative two might be simpler.
The Lazy Hibernate Startup is a good starting point for hibernate at all.
Implement Compareable
All generated Classes have to implement Compareable Interfaces.
To avoid problems with Hibernate, it is highly recommend to implement:
- public int hashCode,
- public int compareTo(MyType ob) and
- public boolean equals(Object obj)
Example:
public int compareTo(Bankinginfo o) {
// equal if ident is equal,
int result = -1;
if (o.getIdent() == this.ident) {
result = 0;
} else if(o.getIdent() == this.ident) {
result=1;
}
return result;
}
@Override
public boolean equals(Object obj) {
if (obj.getClass().isInstance(Bankinginfo.class)) {
Bankinginfo cg= (Bankinginfo) obj;
return compareTo(cg) == 0;
} else {
return super.equals(obj);
}
}
@Override
public int hashCode() {
return ident>0?ident:super.hashCode();
}
Further depending on your database it is necessary to add annotations. For H2 just search for
@Id
and replace it with
@Id
@GenericGenerator(name="gen", strategy="increment")
@GeneratedValue(generator="gen")
If it is necessary or not You will see when you use the generated project - it would not save any values or overwrite always the one with the id 0.
The search and replace can be done if problem occures - this annotations have no impact on the code generation itself.
Build the jar File to feed the Wicketizer
HINT: Do not put a real user and/or real Password into your jar that you will use to feed Wicktetizer! ALWAYS replace it!
I will take it an send it to the badest boys and get paid for it ... .
... Certainly I will not- but I cannot guarantee that no one else will read it during the build process, the server might have a rootkit, whatever.
So always assume I would (and do not lead me into temptation :-).
Within Eclipse
- Select File -> Export ->Java -> jar File -> Next Button
- Click on the src folder in the left window and select the hibernate.cfg.xml in the right window
- Check in the left window the complete package that holds the annotated java class
- Provide a location under "jar File" and provide a name for your jar.
Close everything (you can ignore warnings).
NOW you can go to upload your Feed to http://wicketizer.org:8890/wicket/app/ and you will get your project (Login -> Generation ->follow instructions).
After downloading the generated Eclipse Project, extract it somewhere and import it into Eclipse:
File-> Import...-> General-> Existing Projects into Workspace->Next Button -> browse to where you extracted it.
Go to the Project which holds the generated java classes for Hibernate.
Copy the classes generated by hibernate in your starting project (e.g. src/org.wicketizer.hib.) to the src folder int the generated project and rebuild your project.
Go and see it
Open java perspective and navigate to File de.upsb.mbo.server.Start in the src-gen folder generated and imported Project.
Rightclick on that file, select run as --> Java Application.
In the console of Eclipse you can see that a embedded jetty is started.
You can access the application on http://localhost:8090/mb/app/.
You can give any username longer than 5 digits and any password.
That's all folks ...!
Appendix
Here is a simple Startpoint for your tests - but I would ask all to test a changed version (add a little) and let me know - especially when something fails (and save your jar File - for analysis) .
DDL Statements for a simple Test
create table organisation (
identifier INT4 NOT NULL
, organame VARCHAR(25)
, description VARCHAR(250)
, adat DATE DEFAULT '2000-01-01'::date
);
create table person (
identifier INT4 NOT NULL
, org_identifier INT4 NOT NULL
, name VARCHAR(25)
, firstname VARCHAR(25)
, birthdate DATE DEFAULT '2222-12-31'::date
, adat DATE DEFAULT '2000-01-01'::date
);
create table connection(
identifier INT4 NOT NULL
, per_identifier INT4 NOT NULL
, value VARCHAR(25)
, type VARCHAR(25)
, adat DATE DEFAULT '2000-01-01'::date
);
create table location(
identifier INT4 NOT NULL
, per_identifier INT4 NOT NULL
, value VARCHAR(25)
, type VARCHAR(25)
, adat DATE DEFAULT '2000-01-01'::date
);
ALTER TABLE organisation
ADD CONSTRAINT organisation_pkey
PRIMARY KEY (identifier);
ALTER TABLE person
ADD CONSTRAINT person_pkey
PRIMARY KEY (identifier);
ALTER TABLE connection
ADD CONSTRAINT connection_pkey
PRIMARY KEY (identifier);
ALTER TABLE location
ADD CONSTRAINT location_pkey
PRIMARY KEY (identifier);
ALTER TABLE person
ADD CONSTRAINT FK_person_orga
FOREIGN KEY (org_identifier)
REFERENCES organisation (identifier);
ALTER TABLE connection
ADD CONSTRAINT FK_conection_person
FOREIGN KEY (per_identifier)
REFERENCES person (identifier);
ALTER TABLE location
ADD CONSTRAINT FK_location_person
FOREIGN KEY (per_identifier)
REFERENCES person (identifier);
hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.connection.driver_class">org.h2.Driver</property>
<property name="hibernate.connection.password">modo</property>
<property name="hibernate.connection.url">jdbc:h2:~/mbo_db/dbfile</property>
<property name="hibernate.connection.username">quasi</property>
<property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
<! create of update-->
<property name="hibernate.hbm2ddl.auto">create</property>
<mapping class="de.upsb.mbo.hib.Connections"/>
<mapping class="de.upsb.mbo.hib.Locations"/>
<mapping class="de.upsb.mbo.hib.Persons"/>
<mapping class="de.upsb.mbo.hib.Textinfo"/>
</session-factory>
</hibernate-configuration>
Add your Database Driver to your Project.
Feedback is welcome: info[AT]wicketizer.org
Marcus Bosten
20090419