Recently I had to work with a Oracle instance and had to use a query that uses a subquery like (the IN … statement) this
SELECT * FROM table_a WHERE id IN (...)
The method I had to implement/fix takes an arbitrary number of ids as arguments.. if you get
more than 1000 ids, Oracle will spill a message like this into your fa.. aehm.. onto your console:
"ORA-01795 maximum number of expressions in a list is 1000"
To “fix” this problem, I wrote a small utility class that creates sub-collections of a specific maximum size out of a given collection.
Here it is:
As I keep finding myself searching for orm.xml templates as well as persistence.xml templates for JPA 1.0 and JPA 2.0, I decided to post them here for my own reference and others to find
orm.xml template for JPA 1.0
persistence.xml template for JPA 1.0
orm.xml template for JPA 2.0
persistence.xml template for jpa 2.0
With these templates your favorite IDE should be able to autocomplete the allowed tags on its own.
While migrating a project of mine from JPA2 to Avaje Ebean, I encountered a issue, I wasn’t expecting.
Avaje Ebean does not support the JPA EntityListener Annotations, like
@PrePersist,
@PostPersist,
@PreUpdate,
@PostUpdate,
@PostLoad
Some nice folks on the Ebean Mailinglist directed me to some Documentation about EntityListeners in Ebean including a helpful forum link which finally pointed me to the BeanPersistController Interface in the Ebean Java API .
With that Information, I was able to create a EntityListener that enables the use of the JPA EntityListener Annotations with Ebean.
This Gist shows how I’ve done it:
Questions? Comments? Forks?
I appreciate any kind of feedback!
Recently I hold a presentation about Avaje Ebean on my local Java User Group – The Java Student User Group.
Ebean is a alternative to the established Java Persistence API (JPA) implementations like Hibernate, EclipseLink etc.
It uses the JPA Annotations like
@Table
@Entity
@OneToOne
@OneToMany
@ManyToOne
@ManyToMany
@Column
@Enumerated
@Temporal
etc.
to map your Java Objects to your database tables, but thats all that it has in common with JPA and its implementations.
You can download the ebean presentation.
Today I created a custom JSF 2 Composite Component, but Mojarra threw an error on me, when I tried to use a German Umlaut like ü in my markup, like this
message
descriptionThe server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: javax.servlet.ServletException: javax.faces.view.facelets.FaceletException: Error Parsing /resources/sg/uploadedDoc.xhtml: Error Traced[line: 45] The entity "uuml" was referenced, but not declared.
root cause
javax.servlet.ServletException: javax.faces.view.facelets.FaceletException: Error Parsing /resources/sg/uploadedDoc.xhtml: Error Traced[line: 45] The entity "uuml" was referenced, but not declared.
root cause
java.util.concurrent.ExecutionException: javax.faces.view.facelets.FaceletException: Error Parsing /resources/sg/uploadedDoc.xhtml: Error Traced[line: 45] The entity "uuml" was referenced, but not declared.
root cause
javax.faces.view.facelets.FaceletException: Error Parsing /resources/sg/uploadedDoc.xhtml: Error Traced[line: 45] The entity "uuml" was referenced, but not declared.
note The full stack traces of the exception and its root causes are available in the GlassFish Server Open Source Edition 3.0.1 logs.
To let the SAX-Parser know which additional entities I wanted to use, I simply added the XHTML 1.1 DOCTYPE to the head of the document.
My Component now looks like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:composite="http://java.sun.com/jsf/composite"> <body> <composite:interface> .... </composite:interface> <composite:implementation> .... text Übermorgen ist auch noch ein Tag ... text </composite:implementation> </body> </html> |
Hope this helps some of you out there.
My Spring Security Facelets/JSF2 Tag library has its own chapter in the new book of Décio Heinzelmann Luckow in his new Book Programação Java para a Web
If you want to tunnel OpenMQ through SSH or any firewall, you’ll have to make sure to have fixed ports you can open.
This took me ages, so maybe it helps someone:
I’m starting my imqbrokerd with this command
/home/domdorn/gf/glassfishv3/mq/bin/imqbrokerd \ -javahome /home/domdorn/jdk1.6.0_21/ \ -port 7676 \ -startRmiRegistry \ -rmiRegistryPort 34000 \ -Dimq.jmx.connector.jmxrmi.port=31000 \ -Dimq.jmx.connector.ssljmxrmi.port=32000 \ -Dimq.jmx.rmiregistry.port=34000 \ -Dimq.portmapper.port=7676 \ -Dimq.admin.tcp.port=36000 \ -Dimq.cluster.port=37000 \ -Dimq.cluster_discovery.port=38000 \ -Dimq.cluster.heartbeat.port=39000 \ -Dimq.httpjms.http.servletPort=40000 \ -Dimq.httpsjms.https.servletPort=41000 \ -Dimq.jms.tcp.port=43000 |
which effectively binds imqbrokerd to these ports:
tcp6 0 0 :::34000 :::* LISTEN 22171/java tcp6 0 0 :::43000 :::* LISTEN 22171/java tcp6 0 0 :::31000 :::* LISTEN 22171/java tcp6 0 0 :::7676 :::* LISTEN 22171/java tcp6 0 0 :::36000 :::* LISTEN 22171/java
Now simply connect to the remote host with
ssh REMOTEHOST -L7676:127.0.0.1:7676 -L31000:127.0.0.1:31000 -L34000:127.0.0.1:34000 -L36000:127.0.0.1:36000 -L43000:127.0.0.1:43000 |
Good luck!
As I’m often looking for the correct header of the beans.xml file required for Web Beans / Context and Dependency Injection (CDI) to work, I decided to share this simple header here with you.
If you don’t have anything to declare, create an empty beans.xml like this one
<beans 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/beans_1_0.xsd" /> If you have to declare alternatives or interceptors, do it like this <pre lang='xml'> <beans 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/beans_1_0.xsd"> <alternatives> <stereotype> com.dominikdorn.dc.passwordReset.PasswordResetService </stereotype> <class>com.dominikdorn.dc.passwordReset.StudyGuruPasswordReset</class> </alternatives> </beans> |
A good IDE will help you with creating a proper beans.xml as soon as you specify the xml namespace.
Popular implementations of CDI are
I just got my StarCraft 2 Collectors Edition.
Right after unpacking it, I inserted the DVD and was wondering “They ship a whole DVD with just 2 Files, not more than 3 MB of size?”
The thing is: The DVD has a file system called UDF which supports hidden files and directories. Unlike with normal filesystems in linux, even a ls -lah does not show these files.
1. Unmount the DVD
Make sure to unmount the DVD first.
Close every filemanager and console that has the DVD folder open.
In my Ubuntu installation, the DVD is mounted to /media/cdrom0
Do the following in a console
sudo umount -f /media/cdrom0 |
If it does not work, look which processes still have a lock on the directory using
sudo lsof /media/cdrom0 |
and kill those.
2. Mount the DVD correctly
First, get your own user Id. Most of the times its just 1000.
id |
should return something like this
uid=1000(domdorn) gid=1000(domdorn) groups=4(adm),20(dialout),24(cdrom),46(plugdev),103(fuse),104(lpadmin),114(admin),118(sambashare),1000(domdorn)
Note the values of uid=… and gid=…. (here both are 1000)
Next, mount the DVD the following way:
mount /dev/cdrom /media/cdrom0 -o uid=1000,gid=1000,unhide,umask=0000 |
unhide makes linux show the hidden files on the dvd, uid/gid makes sure you’re allowed to read the files.
3. Start the Installer
Now try to start the installer: Open a console, change to /media/cdrom0 and start it.
cd /media/cdrom0 wine Installer.exe |
If you’re lucky, it now works out of the box and you are finished.
If not (like me), it simply does nothing and we have to do the following.
4. Copy the DVD
If the Installer does not work out of the box, create a folder on your filesystem, e.g.
~/.wine/drive_c/sc2install
and copy the whole DVDs contents to this directory. After this is finished, try to start the Installer from there.
Log into your Battle.net Account.
http://www.battle.net
and Add your CD-Key to your Account. If you don’t have an Battle.net Account yet, create one, you’ll need it anyway.
After you’ve added the Game to your account, download the Windows Installer.
Start up the downloaded installer and select a folder in your wines Drive C. Let it download a few bytes and then quit the installer.
Now copy the files
Installer Tome 1.MPQE.part Installer UI 1.MPQ.part Installer UI 2.MPQE.part
from /media/cdrom0 to the created folder. In my case its ~/.wine/drive_c/sc2download/SC2-WingsOfLiberty-enGB-Installer
Now startup the downloaded installer again.
It should start checking the downloaded files (you might not see a difference in the progress bar, but the CPU goes up, watch with “top”).
After the file check is finished, the installer should start.
For a project at the university, I had to implement an abstract search in an abstract JPA Dao.
Maybe this class comes handy for some of you
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | package com.dominikdorn.rest.dao; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceException; import javax.persistence.TypedQuery; import javax.persistence.criteria.*; import java.lang.reflect.ParameterizedType; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * @author Dominik Dorn */ public class AbstractJpaDao<TYPE> { @PersistenceContext protected EntityManager em; protected Class entityClass; public Class getEntityClass() { return entityClass; } public void setEntityClass(Class entityClass) { this.entityClass = entityClass; } public AbstractJpaDao() { ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass(); this.entityClass = (Class<TYPE>) genericSuperclass.getActualTypeArguments()[0]; } public AbstractJpaDao(Class clazz) { this.entityClass = clazz; } public EntityManager getEm() { return em; } public AbstractJpaDao setEm(EntityManager em) { this.em = em; return this; } @Override public TYPE persist(TYPE item) { if (item == null) throw new PersistenceException("Item may not be null"); em.persist(item); return item; } @Override public TYPE update(TYPE item) { if (item == null) throw new PersistenceException("Item may not be null"); em.merge(item); return item; } @Override public List<TYPE> getAll() { CriteriaQuery cq = em.getCriteriaBuilder().createQuery(); cq.select(cq.from(entityClass)); return em.createQuery(cq).getResultList(); } @Override public TYPE getById(Long id) { if (id == null || id < 1) throw new PersistenceException("Id may not be null or negative"); return (TYPE) em.find(entityClass, id); } @Override public void delete(TYPE item) { if (item == null) throw new PersistenceException("Item may not be null"); em.remove(em.merge(item)); } @Override public List<TYPE> findByAttributes(Map<String, String> attributes) { List<TYPE> results; //set up the Criteria query CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<TYPE> cq = cb.createQuery(getEntityClass()); Root<TYPE> foo = cq.from(getEntityClass()); List<Predicate> predicates = new ArrayList<Predicate>(); for(String s : attributes.keySet()) { if(foo.get(s) != null){ predicates.add(cb.like((Expression) foo.get(s), "%" + attributes.get(s) + "%" )); } } cq.where(predicates.toArray(new Predicate[]{})); TypedQuery<TYPE> q = em.createQuery(cq); results = q.getResultList(); return results; } } |
To instantiate this for an Entity, e.g. “Item”, simply do this
1 2 3 | // get an entityManager somewhere here AbstractJpaDao<Item> dao = new AbstractJpaDao<Item>(); dao.setEm(em); |
now you can use this Data Access Object for your persistence stuff.
To now search for entities in your DB, you can use the method findByAttributes which takes a map<String,String> and searches for appropriate items.
If your Entity looks like this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @Entity public class Item { @Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "ITEM_GEN") @SequenceGenerator(name="ITEM_GEN", allocationSize=25, sequenceName = "item_seq") private long id; @Basic private String name; @Basic private String description; @Basic private Integer size; // constructors, getters, setters |
you could search for an item which names contain “test” like this
1 2 3 4 | Map<String,String> attr = new Hashmap<String,String>(); attr.put("name", "test"); List<Item> results = dao.findByAttributes(attr); |
which comes quite handy in my opinion. Also note, that you don’t have to pre-generate your JPA2 Model classes.