简体   繁体   中英

Automatically Persisting a Complex Java Object

For a project I am working on, I need to persist a number of POJOs to a database. The POJOs class definitions are sometimes highly nested, but they should flatten okay, as the nesting is tree-like and contains no cycles (and the base elements are eventually primitives/Strings). It is preferred that the solution used create one table per data type and that the tables will have one field per primitive member in the POJO. Subclassing and similar problems are not issues for this particular project.

Does anybody know of any existing solutions that can:

  1. Automatically generate a CREATE TABLE definition from the class definition
  2. Automatically generate a query to persist an object to the database, given an instance of the object
  3. Automatically generate a query to retrieve an object from the database and return it as a POJO, given a key.

Solutions that can do this with minimum modifications/annotions to the class files and minimum external configuration are preferred.


Example:

Java classes

//Class to be persisted
class TypeA {
  String guid;
  long timestamp;
  TypeB data1;
  TypeC data2;
}

class TypeB {
  int id;
  int someData;
}

class TypeC {
  int id;
  int otherData;
}

Could map to

CREATE TABLE TypeA (
  guid CHAR(255),
  timestamp BIGINT,
  data1_id INT,
  data1_someData INT,
  data2_id INt,
  data2_otherData INT
);

Or something similar.

I would use the standardized Java Persistence API (JPA), preferably with annotations. Regarding your requirements:

  1. This is not required by the specification but most JPA providers (all major implementations do) support DDL generation from the mapping metadata.
  2. EntityManager#persist(Object entity) does that.
  3. <T> T EntityManager#find(Class<T> entityClass, Object primaryKey) does that.

As hinted, JPA is an API, you need an implementation to use it. My preference goes to Hibernate Entity Manager or EclipseLink (see this previous question ).

You tagged your question as Hibernate. Have you tried using Hibernate for this?

As long as you define well how collections should be mapped (eg, one-to-many), I've found it generally very effective for this kind of thing.

The Hibernate tutorials provide a lot of examples for situations that are similar to the code you provided.

Hibernate can help you solve all the three problems you listed.

(1) You need to annotate your entity classes so Hibernate is able to map between classes/objects to tables/rows. Hibernate uses a convention over configuration approach so it is possible to use just a few annotations and have a complete o/r mapping ready for use. You could use the hibernate.hbm2ddl.auto configuration option to instruct Hibernate to automatically validate/export and schema DDL when the session factory is first created.

(2) / (3) Hibernate has enough information about classes, database schema and mappings to allow it generate SQL statements for simple CRUD operations with minimal effort. You can fine tune how Hibernate loads and persists a tree of objects. Association mapping annotations have the fetch and cascade options that let you specify how associated objects are fetched (lazy / eager) and how operations are propagated through the object tree. Please refer to the Hibernate documentations for the details about these options.

If you are new to Hibernate, I recommend the good Hibernate documentation as reference and the book Java Persistence with Hibernate for the deeper understanding about the framework (it has very good sections about fetching and cascading).

In a typical scenario, Hibernate requires just a bit of configuration (one hibernate.cfg.xml file). You can define the mappings using XML files (no good) or annotations (the "default" option for new projects).

A highly recommended framework is JPersist , an extremely simple Database-to-POJO framework. No XML or annotations needed. I use it it my project because if I want a new table object, I simply create a bean.

The issue though in your situation is your wanting something to setup the database for you. Doing that would be very hard and your asking alot from a framework. With JPersist, you should be able to create a db table from class name and columns from fields, and then use phpMyAdmin's designer to resolve references.

5 min of reading the documentation for JPersist now will save hours in development time later.

JPA provides sufficient options to do this. For example you can use @Embeddable and @Embedded :

@Embeddable
class TypeB {
  int id;
  int someData;
}


class TypeA {
  ....
  @Embedded
  TypeB data1;
}

You can either manually create the underlying schema, or let something like hbm2ddl.auto=update to create it for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM