3

I had recently posted someone about populating a JTable, which is now fully functional. How ever, I am stuck over something else now, I'm hoping to achieve two specific thigns with this thread.

One is to solve my problem, and the other is to have an answer ready for when others stumble across the same problem, cause I never found a proper answer to this yet.

I have the following scenario

Two tables:

games
id pk int
genre int
title varchar ....

genre
id pk int
name varchar ..

One game can only have one genre, but one genre can contain many games.

I'm using Eclipse as my IDE and eclipselink as my JPA provider.

I have generated the classes with the entity wizard provided by eclipse, whom also allowed me to define relationships between the two tables.

The relationships look as follows:

@Entity
@Table(name="games")
public class Game implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@Column(name="Id", unique=true, nullable=false)
private int id;

@Temporal( TemporalType.DATE)
@Column(name="AddDate", nullable=false)
private Date addDate;

@Lob()
@Column(name="Description", nullable=false)
private String description;

@Temporal( TemporalType.DATE)
@Column(name="ModifiedDate", nullable=false)
private Date modifiedDate;

@Temporal( TemporalType.DATE)
@Column(name="ReleaseDate", nullable=false)
private Date releaseDate;

@Column(name="Title", nullable=false, length=255)
private String title;

//bi-directional many-to-one association to Genre
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="Genre", nullable=false)
private Genre genreBean;

//bi-directional many-to-one association to Publisher
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="Publisher", nullable=false)
private Publisher publisherBean;

and the genre

@Entity
@Table(name="genres")
public class Genre implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@Column(name="Id", unique=true, nullable=false)
private int id;

@Column(name="Genre", nullable=false, length=150)
private String genre;

//bi-directional many-to-one association to Game
@OneToMany(mappedBy="genreBean")
private List<Game> games;

I use the following to select all games

        List<Game> games;

    try{
        TypedQuery<Game> selectGamesQuery = entityManager.createQuery("SELECT g FROM Game g", Game.class);
        games = selectGamesQuery.getResultList();
    } catch(Exception e) {
        games = null;
        System.out.println(e);

The problem here is, List games does not contain the genre name, actually, it is empty.

How do I configure the list to contain a game that has the following attributes: id, title, genre-name, publisher-name, releasedate

In my JTable I have tried the following:

        switch(columnIndex){
        case 0:
            return game.getTitle();
        case 1:
            return game.getPublisherBean().getPublisher();
        case 2:
            return game.getGenreBean().getGenre();
        case 3:
            return game.getReleaseDate();
    }

In this case, in my JTable the columns for case 1 and 2 are empty, while the rest works.

So my table content looks like

Battlefield 3 empty empty 3-3-2011

I think with this I should have provided enough info.

Please let me know if there is any mistake or error in the code, or perhaps the select query, as I couldn't even find if I HAVE to write an explicit JOIN query and that it doesnt do that due to the defined relationship.

I'm still a noobie, so please be gentle ^^

Thank you for your time.

kleopatra
  • 51,061
  • 28
  • 99
  • 211
Joey Roosing
  • 2,145
  • 5
  • 25
  • 42
  • "After this, I should be fine writing the rest of my application" - wonderful optimism! – Joel Mar 03 '11 at 13:31
  • Heh, a bit too optimistic perhaps. But the idea sounds nice. But seriously, its the last part I need to fix for this small self teaching project. No doubt ill encounter tons of other problems in my next project. Hell, possibly in the last 5% o this project! But thats fine. :) must admit im breaking my brain over this one with my limited knowledge though.. haha.. i bet its something stupidly easy – Joey Roosing Mar 03 '11 at 13:48
  • 1
    To clarify: you are retrieving non-null values for game.getPublisherBean() and game.getGenreBean(), and null values for their attributes publisher and genre? I'm making this assumption as you did not mention a NullPointerException being thrown in your switch statement. – Kris Babic Mar 03 '11 at 15:08
  • That was exactly the problem. the value was null.. I was very sloppy there. Thanks for the wake up slap. I need to use exception handling better and double check such simple things. thanks again, I can now finish things up for this mini project and start a bigger one with my knew gained knowledge >:D – Joey Roosing Mar 03 '11 at 15:15

3 Answers3

2

to get a bit closer to the problem you could enable finegrained JPA logging by adding the following in your persistence.xml (inside a persistence-unit element):

<properties>
      <property name="eclipselink.logging.level" value="FINEST"/>
</properties>

Then watch your log file and look how the jpql-query gets translated to sql.

Another idea (may sound stupid!): Did you set the foreign key constraints in the database too or only in Persistence Unit?

Hope this helps

Matt Handy
  • 29,855
  • 2
  • 89
  • 112
  • Not a stupid question. And thank you. I have not set it in my database. Should I? I tought JPA would sort all that out for me. ^^;; That property is awsome btw! thanks!I didn't know that one yet ^^ – Joey Roosing Mar 03 '11 at 14:10
  • In fact I do not know if it is really necessary. I did it always this way. So the resulting SQL query would be helpful. You could then send this query to your database directly. – Matt Handy Mar 03 '11 at 14:15
  • When I run it, I get 2 queries. : ReadAllQuery(referenceClass=Game sql="SELECT Id, AddDate, Description, ModifiedDate, ReleaseDate, Title, Genre, Publisher FROM games") [EL Finest]: 2011-03-03 15:45:49.381--ServerSession(2920707)--Connection(4047165)--Thread(Thread[AWT-EventQueue-0,6,main]) and SELECT Id, Genre FROM genres WHERE (Id = ?) not sure what this means :( – Joey Roosing Mar 03 '11 at 14:47
1

are you sure about how you are doing the inserts?? because could happen that when you insert the game you need to insert the genre in the list and update the game someting like this

/**** the var em is the entity manager ****/

Game game = new Game();

game.setId(1);
game.setDesription("This is a example");
game.setTitle("try");
em.persist(game);

Genre genre = new Genre();

genre.setName("blah");
genre.setId(1);

em.persist(genre);

then you need to take the entity already persistence and set to each object because the relation is bidirectional something like this

genre.getGenreBean().add(game);
em.persist(genre);

i hope that this example help you with the problem

EDIT:

If you need the query it's something like this

select G, Game from Genre, IN(g.getGenreBean()) Game

This query return a Collection of Object[] in the position 0 have the genre and the position 1 the game

Jorge
  • 17,896
  • 19
  • 80
  • 126
  • Hey Jogen, thanks for your answer. My problem however is selecting. Im not inserting anything yet. I need to select a game with its genre. In my games table I have a field names genre, which is an INT and holds the id for a genre in the genre table, i need to corresponding name of that genre. So I just want to select, not insert, delete or anything. This answer however is quite nice for in the future. thank you. – Joey Roosing Mar 03 '11 at 14:08
  • I cant really make out the query from your edit. :( I appreciate the help though. I feel like such a newb right now. > – Joey Roosing Mar 03 '11 at 14:52
1

The answer has been resolved.

The problem I had, and the reason I didnt get anything, was because the value was null. It was a very sloppy mistake of my own in the database. I added a record to genre id 2 for some reason rather then id 1 while the game had a genre id of 1, which was empty

(thank you Kris Babic) :)

So my valueable lesson of the day is: Dubble check results in the database, see if you have matching records. Use

    <properties>
      <property name="eclipselink.logging.level" value="FINEST"/>
   </properties>

When debugging

And I have added insert functionality. So thank you for that Jorge.

Thanks for taking the time to answer and read.

So apperantly, the relationships work very nicely using JPA. ALOT nicer then linq to sql in my opinion.

I can now call the following:

game.getPublisherBean().getPublisher();

And I get the wanted result. So "RPG" instead of ""

Joey Roosing
  • 2,145
  • 5
  • 25
  • 42