Discussions

EJB programming & troubleshooting: Problem with EJB Collection from Finder-Method

  1. Problem with EJB Collection from Finder-Method (8 messages)

    Hi!

    I have problems converting data returned as a Collection from an EJB-Finder Method. The SQL is correct, and I get back the correct number of rows. When I convert the Collection, however, I receive the data from the first row only - as many times as there are rows.
    Example: A query returns 26 rows. Reading the data gives me 26 times the first row.

    Here is the method in which I extract the data from the Collection (in which I expect the problem):

      public FormularSeitentext[] getAdminSeitentext(Long index) {
        FormularSeitentext[] formularseitentext = null;
        try {
          AdminseitentextLocalHome home = this.getAdminseitentextLocalHome();
          Collection col = home.findByIndex(index);
          Iterator it = col.iterator();
          formularseitentext = new FormularSeitentext[col.size()];
          int i = 0;
          while(it.hasNext()) {
            AdminseitentextLocalDTO adminseitentextDTO = new AdminseitentextLocalDTO((AdminseitentextLocal)it.next());
            formularseitentext[i] = new FormularSeitentext(""+adminseitentextDTO.getFormblattindex(), adminseitentextDTO.getPositionZeile().intValue(), adminseitentextDTO.getKurztext(), "", adminseitentextDTO.getBeschriftungZeile());
            i++;
          }

        } catch (Exception e) {
          e.printStackTrace();
        }
        return formularseitentext;
      }

    I hope, I was precise enough in describing the Problem - if not, please telle me! :)


    Regards,

    Carsten
  2. The problem is probably in your findByIndex() method. Are you using CMP or BMP? If you are using BMP, check to make sure that you are returning the correct collection of primary keys from the ejbFindByIndex() method.
  3. Hi!

    I'm using CMP. I have also checked the Database if the SQL-calls are correct, the SQL generated from the EJB-QL is working just fine.

    But since you are hinting at the primary keys: the queried table has no primary key. It's rather a collection of values for different indexes. For example, index 4711 might return 4 entries while index 815 returns 26 entries.

    The curious thing is that I receive a Collection with the excact number of Objects (i.e. 4 for 4711 or 26 for 815). When I convert the Collection using the above method, each object returned is different, but contains the same data (the first row returned in all cases).


    Hope this helps,

    Carsten
  4. The PK is definitely your problem. Each Entity must have a unique PK. Probably what is happening is that the EJB server is loading the first record with a given index (say 815) and then thinks "I got record 815, so I will just return this same object over and over again".

    Here are some things you might do to get around the problem:

    1) Use JDBC instead of CMP. This will always work.

    2) Your "Primary Key" for your CMP EJB does not necessarily have to map to the PK of the database table. If you can identify a combination of fields that are always unique in your table, you can "fake" a unique key by define a custom key object that maps to all of those fields:

    // CustomKey field names must match CMP field names
    public class CustomKey {
      public Integer field1;
      public Long field2;
      public String field3;
    }

    See section 10.8.2 (p. 203) of the EJB 2.0 specs, or consult your favorite EJB book or your server's documentation.
  5. Hi there!

    It's been while, I've been busy elsewhere. I tried to reimplement the whole thing as BMP using a custom primary key object.

    While I get the correct results *within* my findByIndex Method, the Primary Key Objects are all the same again (as above, each Object contains the data of the first row) once I extract them from the Collection.

    Curious, I put a number of different PK-Objects into a Collection and when I want to get them back, I get the same number of equal PK-Objects. I'm using a standard Session facade, so I create the Collection in my Entity Bean and extract it in the Session Bean. What exactly happens in between? I mean, the PK-Objects are used to create Local-Interfaces, right? What does the container do?


    Regards,

    Carsten
  6. Hmm. That is strange. Maybe you did not implement the equals() and hashCode() method for your custom key class correctly? Or maybe your EJB server is buggy?

    If you can't get this to work, I suggest you fall back to JDBC, which *will* work, and you won't need to worry about the sometimes strange behavior of Entity Beans. Since you are using a Session Facade, this should be a relatively easy change to make.
  7. Hi!

    I don't really think the server is buggy, it must be my fault. Anyway, thanks for the tips, today I'll try it again with simple, sequential PKs (have those DBA's get to work :). JDBC will be my last resort in this case (and I have the strange feeling I'll use that option... ;).


    My Regards,

    Carsten
  8. Hi again!

    I did find the problem, finally! As it turned out, is was the database - the table was different from the specification I received and contained rubbish. I failed to control this earlier, as our DBAs are normally quite reliable.

    Now, everything is corrected and the code works as suggested.


    Regards,

    Carsten
  9. Congratulations :)