views:

1372

answers:

2

I am currently working on 100+ Java Objects created by someone with no JPA/Hibernate experience into JPA Entities. Their Objects reference other objects based on a Foreign Key in the Class itself. All of the primary Keys are generated outside of the database.

For Example (Just to Illustrate)

Car

@Entity
@Table(name="CAR")
public class Car {

    private Integer id;
    private String name;

    @Id
    @Column(name="CAR_ID")
    public Integer getId() {
     return id;
    }
    public void setId(Integer id) {
     this.id = id;
    }

    @Column(name="CAR_NAME")
    public String getName() {
     return name;
    }
    public void setName(String name) {
     this.name = name;
    }

}

Engine

@Entity
@Table(name="ENGINE")
public class Engine {

    private Integer id;
    private String name;
    private Integer carId;

    @Id
    @Column(name="ENGINE_ID")
    public Integer getId() {
     return id;
    }
    public void setId(Integer id) {
     this.id = id;
    }

    @Column(name="ENGINE_NAME")
    public String getName() {
     return name;
    }
    public void setName(String name) {
     this.name = name;
    }

    @Column(name="CAR_ID")
    public Integer getCarId() {
     return carId;
    }
    public void setCarId(Integer carId) {
     this.carId = carId;
    }

}

Here is what the schema looks like:

CREATE TABLE CAR(CAR_ID INTEGER NOT NULL PRIMARY KEY,CAR_NAME VARCHAR(255))
CREATE TABLE ENGINE(ENGINE_ID INTEGER NOT NULL PRIMARY KEY,CAR_ID INTEGER,ENGINE_NAME VARCHAR(255))
ALTER TABLE ENGINE ADD FOREIGN KEY (CAR_ID) REFERENCES CAR(CAR_ID) ON DELETE CASCADE ON UPDATE CASCADE

Testing Code

 Car c = new Car();
 c.setId(100);
 c.setName("Dodge Intrepid");
 em.persist(c);

 Engine e = new Engine();
 e.setId(999);
 e.setName("V6");
 e.setCarId(c.getId());
 em.persist(e);

 Object entity = em.find(c.getClass(),c.getId());
 em.remove(entity);

So, the Car ID holds a reference to the Engine in the Database. Losing Lazy Loading is not a big deal because we are using an TRANSACTIONAL Entity Manager. I have tested this out and it seems to work fine.

Are there any obvious problems with this that I am missing? I know it does not exactly fit the JPA/Hibernate spec, but I think it works.

+3  A: 

The main thing you're losing is easy navigation through the object graph without having to explicitly fetch associated objects by ID all the time via your data access layer. I understand you're reluctance to go through and convert all of the object IDs into object references, but in the long-run, you're probably better off making that investment. By continuing with your current design, you'll end up writing a lot of extra data access code to fetch related objects every time you need to navigate an association. Plus, it will make it more difficult to model object relationships when the objects are not persisted in the database (e.g. when constructing a new object graph or in unit tests). You're also giving up cascading (transitive) saves and updates.

In short, I think your system will be more difficult to maintain in the long run and navigating object graphs will be quite awkward unless you address this design problem.

Rob H
+1  A: 

Not having any mapped relationships is going to make it almost impossible to have any joins in your HQL Queries or Criteria. So a simple select will work but you could not do " from Engine as eng where eng.car.name = 'DODGE' ". If you at least get the major relationships coded it will make thing alot easier in the long run.

ccclark