This demo presents the track JPA2 of minuteproject.
Starting from a simple model that holds translation information.
This demo will illustrate:
- Generation by console or via config file
- Altering generated code to add JSR 303 (validation) annotation.
- Writing a unit test
- Enrichment facilities and customisation
Prerequisits
- Download Minuteproject last version
- Java 6 in path
- Maven in path
- Install model on myql
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL'; DROP SCHEMA IF EXISTS `tranxy` ; CREATE SCHEMA IF NOT EXISTS `tranxy` DEFAULT CHARACTER SET latin1 ; USE `tranxy` ; -- ----------------------------------------------------- -- Table `tranxy`.`translation_key` -- ----------------------------------------------------- DROP TABLE IF EXISTS `tranxy`.`translation_key` ; CREATE TABLE IF NOT EXISTS `tranxy`.`translation_key` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT , `key_name` VARCHAR(200) NULL DEFAULT NULL , `description` VARCHAR(400) NULL DEFAULT NULL , PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARACTER SET = latin1; -- ----------------------------------------------------- -- Table `tranxy`.`language` -- ----------------------------------------------------- DROP TABLE IF EXISTS `tranxy`.`language` ; CREATE TABLE IF NOT EXISTS `tranxy`.`language` ( `idlanguage` INT(11) NOT NULL AUTO_INCREMENT , `code` VARCHAR(45) NOT NULL , PRIMARY KEY (`idlanguage`) , UNIQUE INDEX `code_UNIQUE` (`code` ASC) ) ENGINE = InnoDB DEFAULT CHARACTER SET = latin1; -- ----------------------------------------------------- -- Table `tranxy`.`traduction` -- ----------------------------------------------------- DROP TABLE IF EXISTS `tranxy`.`traduction` ; CREATE TABLE IF NOT EXISTS `tranxy`.`traduction` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT , `translation` VARCHAR(800) NULL DEFAULT NULL , `language_id` INT(11) NOT NULL , `Key_id` BIGINT(20) NOT NULL , PRIMARY KEY (`id`) , INDEX `fk_traduction_language` (`language_id` ASC) , INDEX `fk_traduction_Key1` (`Key_id` ASC) , CONSTRAINT `fk_traduction_Key1` FOREIGN KEY (`Key_id` ) REFERENCES `tranxy`.`translation_key` (`id` ) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `fk_traduction_language` FOREIGN KEY (`language_id` ) REFERENCES `tranxy`.`language` (`idlanguage` ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB DEFAULT CHARACTER SET = latin1; SET SQL_MODE=@OLD_SQL_MODE; SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
Console generation
By console
In /application run
>start-console.cmd/sh
Fill the 'Data model reverse-engineering' tab
And click on generate
The output goes in /output/trans/JPA2
To build the resulting package execute
>mvn clean package
By command line
Add configuration in /mywork/config
TRANXY-JPA2-1.xml
<!DOCTYPE root> <generator-config xmlns="http://minuteproject.sf.net/xsd/mp-config" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="../config/mp-config.xsd"> <configuration> <conventions> <target-convention type="enable-updatable-code-feature" /> </conventions> <model name="tranxy" version="1.0" package-root="net.sf.mp.demo"> <data-model> <driver name="mysql" version="5.1.16" groupId="mysql" artifactId="mysql-connector-java"></driver> <dataSource> <driverClassName>org.gjt.mm.mysql.Driver</driverClassName> <url>jdbc:mysql://127.0.0.1:3306/tranxy</url> <username>root</username> <password>mysql</password> </dataSource> <primaryKeyPolicy oneGlobal="false" > <primaryKeyPolicyPattern name="autoincrementPattern"></primaryKeyPolicyPattern> </primaryKeyPolicy> </data-model> <business-model> <business-package default="tranxy"> <condition type="package" startsWith="trans" result="translation"></condition> </business-package> <enrichment> <conventions> <!-- manipulate the structure and entities BEFORE manipulating the entities --> <column-naming-convention type="apply-strip-column-name-suffix" pattern-to-strip="ID" /> <reference-naming-convention type="apply-referenced-alias-when-no-ambiguity" is-to-plurialize="true" /> </conventions> </enrichment> </business-model> </model> <targets> <target refname="JPA2" fileName="mp-template-config-JPA2.xml" outputdir-root="../../dev/latvianjug/output/JPA2" templatedir-root="../../template/framework/jpa"> <property name="add-querydsl" value="2.1.2"></property> <property name="add-jpa2-implementation" value="hibernate"></property> <property name="environment" value="remote"></property> </target> <target refname="CACHE-LIB" fileName="mp-template-config-CACHE-LIB.xml" templatedir-root="../../template/framework/cache"> </target> <target refname="LIB" fileName="mp-template-config-bsla-LIB-features.xml" templatedir-root="../../template/framework/bsla"> </target> </targets> </configuration> </generator-config>
Execute by running:
> model-generation.cmd/sh TRANXY-JPA2-1.xml
The ouput goes in/dev/latvianjug/output/JPA2
Make a build:
>mvn clean package
> model-generation.cmd/sh TRANXY-JPA2-1.xml
The ouput goes in
Make a build:
>mvn clean package
Console vs. Command line generation
The generation made by the command line has more enrichment facilities than just working via the console.Example: here the configuration add querydsl integration.
The rest of the demo will focus on the configuration enrichment facilities.
Remark:
Ideally the console should move into a IDE plugin manipulating the configuration.
Resulting artefacts
Summary- A maven pom project
- 3 JPA2 entities (one for each table)
Pom artefact
- provide a jar with name and version number given in configuration
- has hibernate, querydsl, mysql driver, junit dependencies
JPA2 entities
- packaged logically entity starting with 'trans' goes to package translation other goes to 'tranxy' package
- convention 'apply-strip-column-name-suffix' when ending with 'ID'
- DB naming convention used (the foreign key name is composed of the name of the link entity + '_id' is converted into java by provided name stripped from the 'Id' particule.
- primary key strategy:
- Based on auto increment pk when not natural.
- each entity is associated to a metamodel java file to build type safe criteria queries.
persistence.xml: 2 are generated.
MinuteProject artefacts are designed to be tested and ready to be deployed!
MinuteProject artefacts are designed to be tested and ready to be deployed!
- in src/main/resources/META-INF
- with reference to a JTA datasource
- in src/test/resources/META-INF
- with reference to an embedded Connection pool
Global convention
All artefacts have an updatable nature, meaning that you can change the code or add new code and consecutive generation will keep your modifications.
Code
Translation key/** * Copyright (c) minuteproject, minuteproject@gmail.com * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * More information on minuteproject: * twitter @minuteproject * wiki http://minuteproject.wikispaces.com * blog http://minuteproject.blogspot.net * */ /** * template reference : * - name : DomainEntityJPA2Annotation * - file name : DomainEntityJPA2Annotation.vm */ package net.sf.mp.demo.tranxy.domain.translation; //MP-MANAGED-ADDED-AREA-BEGINNING @import@ //MP-MANAGED-ADDED-AREA-ENDING @import@ import java.sql.*; import java.util.Date; import java.util.List; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; import java.io.Serializable; import javax.persistence.*; import net.sf.mp.demo.tranxy.domain.tranxy.Traduction; /** * * <p>Title: TranslationKey</p> * * <p>Description: Domain Object describing a TranslationKey entity</p> * */ @Entity (name="TranslationKey") @Table (name="translation_key") @NamedQueries({ @NamedQuery(name="TranslationKey.findAll", query="SELECT translationKey FROM TranslationKey translationKey") ,@NamedQuery(name="TranslationKey.findByKeyName", query="SELECT translationKey FROM TranslationKey translationKey WHERE translationKey.keyName = :keyName") ,@NamedQuery(name="TranslationKey.findByKeyNameContaining", query="SELECT translationKey FROM TranslationKey translationKey WHERE translationKey.keyName like :keyName") ,@NamedQuery(name="TranslationKey.findByDescription", query="SELECT translationKey FROM TranslationKey translationKey WHERE translationKey.description = :description") ,@NamedQuery(name="TranslationKey.findByDescriptionContaining", query="SELECT translationKey FROM TranslationKey translationKey WHERE translationKey.description like :description") }) public class TranslationKey implements Serializable { private static final long serialVersionUID = 1L; public static final String FIND_ALL = "TranslationKey.findAll"; public static final String FIND_BY_KEYNAME = "TranslationKey.findByKeyName"; public static final String FIND_BY_KEYNAME_CONTAINING ="TranslationKey.findByKeyNameContaining"; public static final String FIND_BY_DESCRIPTION = "TranslationKey.findByDescription"; public static final String FIND_BY_DESCRIPTION_CONTAINING ="TranslationKey.findByDescriptionContaining"; @Id @Column(name="id" ) @GeneratedValue(strategy = GenerationType.AUTO) private Long id; //MP-MANAGED-ADDED-AREA-BEGINNING @key_name-field-annotation@ //MP-MANAGED-ADDED-AREA-ENDING @key_name-field-annotation@ //MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @ATTRIBUTE-key_name@ @Column(name="key_name", length=200, nullable=true, unique=false) private String keyName; //MP-MANAGED-UPDATABLE-ENDING //MP-MANAGED-ADDED-AREA-BEGINNING @description-field-annotation@ //MP-MANAGED-ADDED-AREA-ENDING @description-field-annotation@ //MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @ATTRIBUTE-description@ @Column(name="description", length=400, nullable=true, unique=false) private String description; //MP-MANAGED-UPDATABLE-ENDING //MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @traductions-field-translation_key@ @OneToMany (targetEntity=net.sf.mp.demo.tranxy.domain.tranxy.Traduction.class, fetch=FetchType.LAZY, mappedBy="key", cascade=CascadeType.REMOVE)//, cascade=CascadeType.ALL) private Set <Traduction> traductions = new HashSet<Traduction>(); //MP-MANAGED-UPDATABLE-ENDING /** * Default constructor */ public TranslationKey() { } /** * All field constructor */ public TranslationKey( Long id, String keyName, String description) { //primary keys setId (id); //attributes setKeyName (keyName); setDescription (description); //parents } public TranslationKey flat() { return new TranslationKey( getId(), getKeyName(), getDescription() ); } public Long getId() { return id; } public void setId (Long id) { this.id = id; } //MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @GETTER-SETTER-key_name@ public String getKeyName() { return keyName; } public void setKeyName (String keyName) { this.keyName = keyName; } //MP-MANAGED-UPDATABLE-ENDING //MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @GETTER-SETTER-description@ public String getDescription() { return description; } public void setDescription (String description) { this.description = description; } //MP-MANAGED-UPDATABLE-ENDING //MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @traductions-getter-translation_key@ public Set<Traduction> getTraductions() { if (traductions == null){ traductions = new HashSet<Traduction>(); } return traductions; } public void setTraductions (Set<Traduction> traductions) { this.traductions = traductions; } public void addTraductions (Traduction traduction) { getTraductions().add(traduction); } //MP-MANAGED-UPDATABLE-ENDING //MP-MANAGED-ADDED-AREA-BEGINNING @implementation@ //MP-MANAGED-ADDED-AREA-ENDING @implementation@ }Language
/** * Copyright (c) minuteproject, minuteproject@gmail.com * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * More information on minuteproject: * twitter @minuteproject * wiki http://minuteproject.wikispaces.com * blog http://minuteproject.blogspot.net * */ /** * template reference : * - name : DomainEntityJPA2Annotation * - file name : DomainEntityJPA2Annotation.vm */ package net.sf.mp.demo.tranxy.domain.tranxy; //MP-MANAGED-ADDED-AREA-BEGINNING @import@ //MP-MANAGED-ADDED-AREA-ENDING @import@ import java.sql.*; import java.util.Date; import java.util.List; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; import java.io.Serializable; import javax.persistence.*; import net.sf.mp.demo.tranxy.domain.tranxy.Traduction; /** * * <p>Title: Language</p> * * <p>Description: Domain Object describing a Language entity</p> * */ @Entity (name="Language") @Table (name="language") @NamedQueries({ @NamedQuery(name="Language.findAll", query="SELECT language FROM Language language") ,@NamedQuery(name="Language.findByCode", query="SELECT language FROM Language language WHERE language.code = :code") ,@NamedQuery(name="Language.findByCodeContaining", query="SELECT language FROM Language language WHERE language.code like :code") }) public class Language implements Serializable { private static final long serialVersionUID = 1L; public static final String FIND_ALL = "Language.findAll"; public static final String FIND_BY_CODE = "Language.findByCode"; public static final String FIND_BY_CODE_CONTAINING ="Language.findByCodeContaining"; @Id @Column(name="idlanguage" ) @GeneratedValue(strategy = GenerationType.AUTO) private Integer idlanguage; //MP-MANAGED-ADDED-AREA-BEGINNING @code-field-annotation@ //MP-MANAGED-ADDED-AREA-ENDING @code-field-annotation@ //MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @ATTRIBUTE-code@ @Column(name="code", length=45, nullable=false, unique=false) private String code; //MP-MANAGED-UPDATABLE-ENDING //MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @traductions-field-language@ @OneToMany (targetEntity=net.sf.mp.demo.tranxy.domain.tranxy.Traduction.class, fetch=FetchType.LAZY, mappedBy="language", cascade=CascadeType.REMOVE)//, cascade=CascadeType.ALL) private Set <Traduction> traductions = new HashSet<Traduction>(); //MP-MANAGED-UPDATABLE-ENDING /** * Default constructor */ public Language() { } /** * All field constructor */ public Language( Integer idlanguage, String code) { //primary keys setIdlanguage (idlanguage); //attributes setCode (code); //parents } public Language flat() { return new Language( getIdlanguage(), getCode() ); } public Integer getIdlanguage() { return idlanguage; } public void setIdlanguage (Integer idlanguage) { this.idlanguage = idlanguage; } //MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @GETTER-SETTER-code@ public String getCode() { return code; } public void setCode (String code) { this.code = code; } //MP-MANAGED-UPDATABLE-ENDING //MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @traductions-getter-language@ public Set<Traduction> getTraductions() { if (traductions == null){ traductions = new HashSet<Traduction>(); } return traductions; } public void setTraductions (Set<Traduction> traductions) { this.traductions = traductions; } public void addTraductions (Traduction traduction) { getTraductions().add(traduction); } //MP-MANAGED-UPDATABLE-ENDING //MP-MANAGED-ADDED-AREA-BEGINNING @implementation@ //MP-MANAGED-ADDED-AREA-ENDING @implementation@ }Tranduction
/** * Copyright (c) minuteproject, minuteproject@gmail.com * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * More information on minuteproject: * twitter @minuteproject * wiki http://minuteproject.wikispaces.com * blog http://minuteproject.blogspot.net * */ /** * template reference : * - name : DomainEntityJPA2Annotation * - file name : DomainEntityJPA2Annotation.vm */ package net.sf.mp.demo.tranxy.domain.tranxy; //MP-MANAGED-ADDED-AREA-BEGINNING @import@ //MP-MANAGED-ADDED-AREA-ENDING @import@ import java.sql.*; import java.util.Date; import java.util.List; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; import java.io.Serializable; import javax.persistence.*; import net.sf.mp.demo.tranxy.domain.translation.TranslationKey; import net.sf.mp.demo.tranxy.domain.tranxy.Language; /** * * <p>Title: Traduction</p> * * <p>Description: Domain Object describing a Traduction entity</p> * */ @Entity (name="Traduction") @Table (name="traduction") @NamedQueries({ @NamedQuery(name="Traduction.findAll", query="SELECT traduction FROM Traduction traduction") ,@NamedQuery(name="Traduction.findByTranslation", query="SELECT traduction FROM Traduction traduction WHERE traduction.translation = :translation") ,@NamedQuery(name="Traduction.findByTranslationContaining", query="SELECT traduction FROM Traduction traduction WHERE traduction.translation like :translation") }) public class Traduction implements Serializable { private static final long serialVersionUID = 1L; public static final String FIND_ALL = "Traduction.findAll"; public static final String FIND_BY_TRANSLATION = "Traduction.findByTranslation"; public static final String FIND_BY_TRANSLATION_CONTAINING ="Traduction.findByTranslationContaining"; @Id @Column(name="id" ) @GeneratedValue(strategy = GenerationType.AUTO) private Long id; //MP-MANAGED-ADDED-AREA-BEGINNING @translation-field-annotation@ //MP-MANAGED-ADDED-AREA-ENDING @translation-field-annotation@ //MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @ATTRIBUTE-translation@ @Column(name="translation", length=800, nullable=true, unique=false) private String translation; //MP-MANAGED-UPDATABLE-ENDING @ManyToOne (fetch=FetchType.LAZY , optional=false) @JoinColumn(name="Key_id", referencedColumnName = "id", nullable=false, unique=false ) private TranslationKey key; @Column(name="Key_id", nullable=false, unique=false, insertable=false, updatable=false) private Long key_; @ManyToOne (fetch=FetchType.LAZY , optional=false) @JoinColumn(name="language_id", referencedColumnName = "idlanguage", nullable=false, unique=false ) private Language language; @Column(name="language_id", nullable=false, unique=false, insertable=false, updatable=false) private Integer language_; /** * Default constructor */ public Traduction() { } /** * All field constructor */ public Traduction( Long id, String translation, Integer language, Long key) { //primary keys setId (id); //attributes setTranslation (translation); //parents this.key = new TranslationKey(); this.key.setId(key); //ID this.language = new Language(); this.language.setIdlanguage(language); //IDLANGUAGE } public Traduction flat() { return new Traduction( getId(), getTranslation(), getLanguage_(), getKey_() ); } public Long getId() { return id; } public void setId (Long id) { this.id = id; } //MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @GETTER-SETTER-translation@ public String getTranslation() { return translation; } public void setTranslation (String translation) { this.translation = translation; } //MP-MANAGED-UPDATABLE-ENDING public TranslationKey getKey () { return key; } public void setKey (TranslationKey key) { this.key = key; } public Long getKey_() { return key_; } public void setKey_ (Long key) { this.key_ = key; } public Language getLanguage () { return language; } public void setLanguage (Language language) { this.language = language; } public Integer getLanguage_() { return language_; } public void setLanguage_ (Integer language) { this.language_ = language; } //MP-MANAGED-ADDED-AREA-BEGINNING @implementation@ //MP-MANAGED-ADDED-AREA-ENDING @implementation@ }
persistence.xml in test directory
Persistence.xml in main directory
The persistence.xml provides a configuration with embedded connection pool.
If the user want to use a remote connection pool accessed by JNDI, the user has to put property
Under the target JPA2 node.
Add the imports between the MP-MANAGED-ADDED-AREA-BEGINNING @import@ and MP-MANAGED-ADDED-AREA-ENDING @import@ comments
Add the annotation between MP-MANAGED-ADDED-AREA-BEGINNING @xxxx-field-annotation@ and MP-MANAGED-ADDED-AREA-ENDING @xxxx-field-annotation@ comments
Now further generation will keep your added code.
The validation scenario has been inspired by this link.
Execute with
>mvn clean package
The 2 tests pass.
<?xml version="1.0"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <!--MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @PERSISTENCE-UNIT-tranxy@--> <persistence-unit name="tranxy" transaction-type="RESOURCE_LOCAL"> <!--MP-MANAGED-UPDATABLE-ENDING--> <provider>org.hibernate.ejb.HibernatePersistence</provider> <!-- tranxy --> <class>net.sf.mp.demo.tranxy.domain.tranxy.Language</class> <class>net.sf.mp.demo.tranxy.domain.tranxy.Traduction</class> <!-- translation --> <class>net.sf.mp.demo.tranxy.domain.translation.TranslationKey</class> <properties> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver" /> <property name="hibernate.connection.url" value="jdbc:mysql://127.0.0.1:3306/tranxy" /> <property name="hibernate.connection.username" value="root" /> <property name="hibernate.connection.password" value="mysql" /> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> </properties> </persistence-unit> </persistence>
Persistence.xml in main directory
The persistence.xml provides a configuration with embedded connection pool.
If the user want to use a remote connection pool accessed by JNDI, the user has to put property
lt;property name="environment" value="remote" />
Alter Generated Code and Unit Test
With Minuteproject one shot-generation as 'too-much-often' seen is over!
Be ready for continuous-refactoring of your backend!
Add a validation annotation
In Language class
//MP-MANAGED-ADDED-AREA-BEGINNING @import@ import javax.validation.constraints.*; //MP-MANAGED-ADDED-AREA-ENDING @import@ ... //MP-MANAGED-ADDED-AREA-BEGINNING @code-field-annotation@ @Size(min = 2) //MP-MANAGED-ADDED-AREA-ENDING @code-field-annotation@ //MP-MANAGED-UPDATABLE-BEGINNING-DISABLE @ATTRIBUTE-code@ @Column(name="code", length=45, nullable=false, unique=false) private String code;
Add the imports between the MP-MANAGED-ADDED-AREA-BEGINNING @import@ and MP-MANAGED-ADDED-AREA-ENDING @import@ comments
Add the annotation between MP-MANAGED-ADDED-AREA-BEGINNING @xxxx-field-annotation@ and MP-MANAGED-ADDED-AREA-ENDING @xxxx-field-annotation@ comments
Now further generation will keep your added code.
Unit test
In src/test/java add the TranxyTest class in package mytestThe validation scenario has been inspired by this link.
package mytest; import javax.persistence.*; import javax.validation.*; import javax.validation.constraints.*; import static junit.framework.Assert.*; import org.junit.*; import net.sf.mp.demo.tranxy.domain.tranxy.*; public class TranxyTest { EntityManagerFactory emf = Persistence.createEntityManagerFactory("tranxy"); EntityManager em = emf.createEntityManager(); @Test public void testLanguage() { EntityTransaction tx = em.getTransaction(); tx.begin(); Language language = new Language(); language.setCode("FR"); em.persist(language); tx.commit(); } @Test public void testTooSmallLanguage() { try { EntityTransaction tx = em.getTransaction(); tx.begin(); Language language = new Language(); language.setCode("F"); em.persist(language); fail("Expected ConstraintViolationException wasn't thrown."); tx.commit(); } catch (ConstraintViolationException e) { assertEquals(1, e.getConstraintViolations().size()); ConstraintViolation violation = e.getConstraintViolations().iterator().next(); assertEquals("code", violation.getPropertyPath().toString()); assertEquals( Size.class, violation.getConstraintDescriptor().getAnnotation().annotationType()); } } @Before public void clean () { EntityTransaction tx = em.getTransaction(); tx.begin(); Query q = em.createQuery("delete Language"); q.executeUpdate(); tx.commit(); } }
Execute with
>mvn clean package
Download
The result can be downloaded on google code minuteproject.
No comments:
Post a Comment