Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have two classes that I want related to each other in an JEE application using JPA2. In an OO world, I would say that a Chatroom has an attribute List messages. In the relational world composition doesn't exist like this. If I weren't involving a database at all, I would definitely code these two things as a composition the messages inside of the Chatroom. But since I'm using ORM with the JPA2 spec I've decided to try to create the @Entity objects as written below with the fact that they'll be mapped to the database in mind.

My question is: Should I be doing this? Is it appropriate to break out the @Entity classes to support what feels like the more relational approach? Or should I just design from an OO perspective, and try to ignore the fact that there's an ORM driving it from below? Right now I'm driving my design from the database side, but should I be doing it the other way? Are there implications I'm missing about doing it this way?

package org.janp.castlerock;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Chatroom {
    private String name;

    @Id
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}



package org.janp.castlerock;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
public class Message {
    private int id;
    private Chatroom chatroom;
    private Date timestamp;
    private String text;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    @Temporal(TemporalType.TIMESTAMP)
    public Date getTimestamp() {
        return timestamp;
    }
    public void setTimestamp(Date timestamp) {
        this.timestamp = timestamp;
    }

    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }

    @ManyToOne
    @JoinColumn(name="name")
    public Chatroom getChatroom() {
        return chatroom;
    }
    public void setChatroom(Chatroom chatroom) {
        this.chatroom = chatroom;
    }
}
share|improve this question
    
What use is an O/RM that doesn't support mapping lists? Just use Hibernate. There's too much detritus from the infrastructure leaking into your object model (including the annotations). JPA is a reverse-engineered "spec" from where Hibernate was 3 years ago. –  Mike Brown Apr 26 '12 at 18:45
    
It does support mapping lists, and I could do that. My question is should I write this in an OO way, with the lists, or in a relational way, with the current structure. –  Jazzepi Apr 26 '12 at 18:53

4 Answers 4

up vote 2 down vote accepted

Theoretically, neither of the these approaches is truly 'OO', since you're exposing all of the internal state outward (there is no encapsulation). So, from this perspective, your question really becomes: should I add Collection attributes/getters/setters to my DAO (Data Access Objects). As this will further expose internal state, I'm tempted to answer with 'no'.

Moreover, because you are making assumptions on the expected use of your objects (asking for the list will retrieve all the messages, without any selection), you might actually inspire programmers to bypass the optimization strategies a database might give you. To elucidate this by example; you might bypass an efficient index by retrieving all objects and sorting or selecting them afterwards.

On the practical side, adding these list accessors is often useful. It allows for a more natural way of navigating through your object graph and often is more efficient for small sets, since you have more control over caching.

I would like to end by giving a piece of sound advice. Create a clear delineation between your DAO's and your models. Try not to work directly on DAO's from a GUI and consider adding a business logic layer in between. It might be slightly more difficult at the start, but it will reduce complexity and promotes reusability. Perhaps, when your business logic layer is complete, you'll find you don't need many of those pesky DAO's after all. You might actually find data storage solutions which operate more efficiently by bypassing the overhead of DB calls.

share|improve this answer
    
+1 and answer for definitely addressing the main content of my question. I ran into exactly what you were talking about with the list. If you just use getMessages() then you have to get them ALL, then sort them and filter in Java-land. If it's done in the database-way as I have it coded above, you can filter, and sort, using JPQL so the result set you get back is exactly what you want. I also think the DB is going to be more efficient at doing this sorting/filtering than whatever Java-land code you might right. –  Jazzepi Apr 27 '12 at 14:39
    
The truth, as always, is really convoluted. Imagine a relation with eight entries and you select four of them with a separate query? Horrible overhead. Say, you have a 8000 entries and you select units of 1000 with separate queries? Perhaps worth doing? Anyways, thanks for asking the question, it got me into my thinking phase. –  Dibbeke May 1 '12 at 21:52

Write your objects as objects. Let the mapper handle the relational side of things. I'd much rather given a chatroom say:

Collection messages=chatroom.getMessages();

instead of having to do a new query of Messages where the ChatroomId == chatroom.getId() especially seeing that Java doesn't have a LINQ equivalent

share|improve this answer

I am currently working with an ORM (Doctrine 2 in PHP) and I work like this :

For example I had to build a media library management component with the following associated entities :

  • Media (contains the actual media description and path)
  • MediaType (video, image or audio)
  • MediaExtension [by type] (.mp4, .jpg, .mp3, etc.)

These entities are used to define my DB structure and relation between object (an entity could be managing a junction table as well, so they don't map 1 to 1 with my database)

These three entities where then injected in the model that contained all the logic and since all these entities were relating with each other to manage the library, all the required code in contained is my model class.

So in your case, you could build a model that would manage the chat with the following entities :

  • Room (define the actual chatroom (rules, admins, topic, name, etc.)
  • Message (messages exchanged between users)
  • Users (this will only manage the part where a user create a new message and maybe a few options like the display name. This entity would also be present in your user model which manage user creation and in depth modification)

This would be closer to a Domain Driven Design (the data management is mapped to fit application requirements, gives a more user friendly feel to the application) as opposed to a Data Driven Design (where the database structure guide how the application requirement are implanted)

share|improve this answer

Just my two cents here. Since starting to work with asp.net mvc along with entity framework, that even though it's real easy to get me a database representation of a table, that really may not be what I need.

I've found that creating what some people call a ViewModel, a class that has everything you need to represent the actual object you're going to work with, has actually been a pretty good idea. While it seems that you're creating extra work, what with a base model which looks like a table, and second model that just recreates those properties (and/or adds more depending on the situation) I think the flexibility is a better trade off.

So I'm going to agree with the others here and say, write your 'viewModels' to match what you really need, and just map those properties off to an 'entity' model when you need to either save or access them from the database.

Hope this helps some, and good luck on your project.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.