Should I be able to persist a JFrame (or gui components in general)?

#1

    I did the following:

1. (using Netbeans 8.02 & last available java 7 sdk) I sort of follow your tutorial(s) while applying the ideas to a sample that came with the IDE called GUIFormExamples (under samples).

2. Specifically, I worked with the ContactEditor as main. I made a new class called Contact, and modeled after your Point class from your tutorial. This whole process worked and end result was working persistence as seen in explorer. But (mostly for those who might encounter the same issues I did) I did have to do the following. I had first tried without the EE version of Netbeans (and not having any separate Java EE stuff installed). What happened is I couldn't import javax.persistence... I now believe I *may* not have needed to get the EE version of Netbeans. But I did. And still I had the problem. What fixed it was something I *could* have done with the regular Netbeans: go to top level project properties (my case GUIFormExamples) and add libraries. Add Java EE 6 API Library. While your here, this is also where I needed to add the objectdb.jar file (from your download). And finally, on my win10 system with java 7 jdk only (shouldn't matter), the only way your bin files worked was double clicking your jar files (none of the exe's worked--couldn't find java if I tried them from command line).

3. Basically what I did to the sample was, I morphed the interface of the ContactEditor a bit to let me cycle thru a List of my Contact objects, which just had first and last name for persistence to keep simple. I could Add, Delete, and Arrow from contact to contact, with various persistence operations working fine (hardest part was running up against what I always think of as the weird Java iterators--I learn them, and then forget and bump into them again--probably there's a better way to have done what I was doing with the arrow buttons--than to have tried to use iterators with no concept of current record--but I digress--I got them working anyway).

4. The point is, it has been a goal of mine for some time now, to find a way of programming basic "editor" interfaces like this, so that I am not spending a long time (I'm slow) programming what I'll call "mapping the UI to the database". I was happy with how your object db compared to my little work with LINQ/C#. I can see how LINQ tries to solve the problem by preserving the status quo, in that a database drives the code. With the little toying with ObjectDb, I can see that the code drives the database, and I like this a lot so far. However, in writing the Contact class, I realized I was still mapping my Contact class to the Editor interface. I realize that I'm probably going against any pro developer/ enterprise multi tiered philosophy--nevertheless--I decided that I would like to somehow persist the Interface itself. Admittedly, I haven't figured out how I will "efficiently" do this--I am encouraged by the understanding that objectdb can be very selective in what parts of classes it persists. But I realize that if I'm just going to, for example, persist a set / list of forms, it doesn't quite make sense--at least it "seems" inefficient that the user might cycle through a list of contacts in such a way that there is a "different" form for each one...but if I thought about Java references I'm sure I'd figure something efficient out.

5. BUT, when I try to persist a JFrame as a test, it all compiles, but I get a runtime error--

Exception in thread "AWT-EventQueue-0" java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/persistence/Persistence

Here is are two hopefully telling sections of my new quick test project that just has a JFrame attempting to persist.

//i tried this with and without Serializable, and with and without exposing the @Id

//from NewJFrame.java.........................................................................................

import java.io.Serializable;
import javax.persistence.*;

/**
*
* @author Sammy Guergachi <sguergachi at gmail.com>
*/
@Entity
public class NewJFrame extends javax.swing.JFrame implements Serializable {
    private static final long serialVersionUID = 1L;
   
    @Id @GeneratedValue
    private long id;
   
    public NewJFrame() {
        initComponents();
    }

//more stuff etc...................................


// main from JavaApplication1.java.....................................

public static void main(String[] args) {

        emf = Persistence.createEntityManagerFactory("$objectdb/db/thecontacts.odb");
        //emf = Persistence.createEntityManagerFactory("objectdb://localhost/thecontacts.odb;user=admin;password=admin");
        em = emf.createEntityManager();
        Query qryListContacts = em.createQuery("select c from NewJFrame c");
        contacts = qryListContacts.getResultList();

        NewJFrame a;
        a = new NewJFrame();
        a.setVisible(true);

        em.getTransaction().begin();
        contacts.add(a);
        em.getTransaction().commit();

    }

//.............................................................

Note that "thecontacts" is a new database...the file from the first sample based ContactEditor test was called "contacts"

I tried accessing thru server process and without server process as seen uncommented--both were from working code from sample test.

 

Any ideas on the runtime error, or how I could reduce amount of code to map UI to a database to as little as possible, would be appreciated.

 

#2

Update...I got a bit eager trying this without paying attention... The exception was due to having chosen "Java EE 6 API Library" when for my first working test I had chosen "Java EE 7 API Library"

Also...I was really hasty in trying to get a query result when the database didn't yet have the object type. I temporarily got rid of the query, and changed the contacts.add(a) to em.persist(a), and the NewJFrame was persisted just fine.

Now I'll have to see how far I can take this, and whether it might lead to anything interesting. Perhaps no need to reply at this point. I have some more experimenting to do.

#3

Last update...promise. I discovered that (as I should have understood from tutorial) fields of Entity classes must indeed be persistable types. So I made a user component that extends JTextField, and set it as @Embeddable. It persists. However, when I do "select ce.pJTextField1.text from ContactEditor ce" the text field cannot be found. When I do "select ce.pJTextField1.getText() from ContactEditor ce" it returns empty strings, but there should have been text at the time this ran:

System.out.println(a.pJTextField1.getText()); //did have text when ran
em.getTransaction().begin();
em.persist(a);
em.getTransaction().commit();
System.out.println(a.pJTextField1.getText()); //did have text when ran

By the way, to clarify--- a is @Entity ContactEditor extends JFrame

So, at this point, I'm wondering what is supposed to happen to the fields of Embedded classes. Looking it up, if they are persistable, they should be fine--and the "text" field is java.lang.String, thus fine. But maybe its a problem because of the extending?

Final comment-- even if it turns out as I think about it, that just defining the interface is not generally enough to define the persistence, 2 things will still be true. First, there ought to be a system that at least takes into account the idea that a process of mapping "will" be going on for many applications, and eases the burden of coding somehow. This may exist, and I just don't get it, or whatever. And second, the idea of persisting interface components will still be "interesting" to me. Any help in this regard would be appreciated.

#4

> Last update...promise. I discovered that (as I should have understood from tutorial) fields of Entity classes must indeed be persistable types.

Any serializable type may be supported but this is disabled by default.

ObjectDB Support

Reply