With JPA, there finally is an ORM standard and every major IDE has support for it. Today I will show you how to map your data with IntelliJ IDEA. I also use the brand new TopLink 11g preview (a JPA implementation), but you can try this at home with every JPA-implementation.
A few weeks ago Peter showed some AMIS employees (including me) the TopLink workbench. I really was amazed how good is was. And I felt a bit bad that I didn’t knew that such a tool existed. I wanted to use the tool myself. I fiddled around with it and really love it. But I wanted to get JPA-annotations, not the TopLink XML files. Whilst searching on how to do that I discovered that every major IDE supported JPA annotation generation. Last year I mainly used iBatis and Spring-JDBC and kind of forgot about JPA, so the ‘amazing new things’ I’m about to tell might be pretty ancient by now 😉
Creating the mapping and data sources
Create a project in IntelliJ and add libraries for JUnit, Oracle JDBC (OJDBC14.jar) and the libraries for your JPA-implementation. I’m using TopLink 11g preview so I have to add persistence.jar, toplink.jar and xmlparserv2.jar
To validate your persistence classes and queries properly you have to add a data source. Go to Tools, Data Sources. Click on the plus icon in the upper left corner of the dialog.
Click on the plus icon and search for your JDBC-driver. It’s usually sufficient to hit the ‘Find Driver Classes’ button, but sometimes you have to look up the driver yourself.
The next step is the database url, user name, password and schema name. You can click the test connection to test the connection and with the refresh tables button you can test some more.
Right click your project, new, add persistence unit. My persistence unit is called Scott. IntelliJ generates the XML for you. You have to add some properties to make sure the application works outside IntelliJ. Overwrite the <persistence-unit> with
<persistence-unit name="scott">
<properties>
<property name="toplink.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<property name="toplink.jdbc.url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
<property name="toplink.jdbc.user" value="scott"/>
<property name="toplink.jdbc.password" value="tiger"/>
<property name="com.intellij.javaee.persistence.datasource" value="Scott"/>
</properties>
</persistence-unit>
Note that the last property is needed for proper validation of the persistence classes and queries, otherwise you wil see red underlinings everywhere. You can remove the line when you deploy your project to a web server.
To create the mappings you just have to do some clicking. Right click your project, Generate persistence mapping and pick by database schema.
In the dialog that pops up you have to add some things:
- choose Datasource: Scott
- package: nl.amis.domain.scott
- tick add to persistence unit and pick scott
- deselect Bonus and Salgrade because we only want the Emp and Dept table.
Note that the deptno field of emp is deselected. This is because it’s a foreign key (hence the fk on the table icon) and JPA knows you probably don’t want to use that foreign key. And JPA is right, we want a department object in our employee object.
Select the Emp table and click on the plus icon to add a relation.
In the Employee object we want to select a Department, so add an attribute department and leave type on <entity>. In the department section we want to be able to select a list of employees. Change the Type to java.util.List and enter the attribute name employees.
When you’re using an ancient database without relations you can enter a source an target column, but that isn’t necessary becasue JPA is pretty smart.
Select src directory when you can choose between the resources and src directory.
Go to the package nl.amis.domain.scott and look what IntelliJ did for you. Of course there are a lot of annotations that aren’t really necessary, but they won’t hurt performance and now it’s more clear what is actually happening.
In the DeptEntity class you can see there is a one to many relation to employee:
@OneToMany(mappedBy = "department")
public List<EmpEntity> getEmployees() {
return employees;
}
The final step is adding the used classes to persistence.xml (copy these tags just above <properties>)
<class>nl.amis.domain.scott.EmpEntity</class>
<class>nl.amis.domain.scott.DeptEntity</class>
Querying your data
Now it’s finally time to query the data. Let’s have a look at this simple test case
public
class
TestTopLinkJPA extends TestCase {
private static final Logger log = Logger.getLogger(TestTopLinkJPA.class);
private EntityManagerFactory emf = null;
private String s;
protected void setUp() {
emf = Persistence.createEntityManagerFactory("scott");
log.debug("EntityManagerFactory created");
}
protected void tearDown() throws Exception {
emf.close();
log.debug("EntityManagerFactory closed");
}
public void testScott() throws Exception {
EntityManager em = emf.createEntityManager();
Query query = em.createQuery("select e from EmpEntity e");
List<EmpEntity> list = query.getResultList();
for (int i = 0; i < list.size(); i++) {
EmpEntity e = list.get(i);
System.out.println(e.getEname() + ", dept location: " + e.getDepartment().getLoc());
}
}
}
The coolest thing about IntelliJ is that ‘they’ validate your queries! Lets add ‘where e.’ and hit ctrl-space
How cool is that!? Let’s change EmpEntity to EmpEntaty:
This will make your work so much easier, no more stupid typo’s or hours of searching because you always write Entaty and don’t know what’s wrong with that.
Conclusion
After a few hours with JPA I really love it. I’m always a bit conservative and stuck to iBatis and Spring-JDBC for too long. Not that there’s anything wrong with those two, but JPA can make you job easier (and of course it always good to check out other tools). The four major IDE’s (Eclipse, IntelliJ, NetBeans and JDeveloper) are really competing with each other and we as users get betters tools because of that competition. A few years ago it would’ve taken ages to get some proper tooling for new frameworks and now I’m suprised good tools are already out there.
Thanks for the info. It’s good to know that Alexa is starting to normalize
I have 2GB of RAM. With the Scott schema it’s pretty fast. With a large database it gets a little bit slower, but 10 minutes is too long. Did you notice the unselect all button in the toolbar above the check-boxes?
How much RAM do you have? I have 2GB, but every time I tried to check one of the deselected check-boxes in the Import Database Schema dialog, I had to wait 10-15 minutes to get my processor back. With dozens to go, this just isn’t going to work.