Web-Applikation mit Persistence-Unit

AAF

Grünschnabel
Hallo Community

Ich hab Probleme selber eine Persistence-Unit in NetBeans zu erstellen. Dabei verwende ich den Glassfish V2 und TopLink. Ich habe eine Tabelle Menu:

Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ec;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

/**
 *
 * @author adrian
 */
@Entity
@Table(name = "menu")
@NamedQueries({@NamedQuery(name = "Menu.findById", query = "SELECT m FROM Menu m WHERE m.id = :id"), @NamedQuery(name = "Menu.findByName", query = "SELECT m FROM Menu m WHERE m.name = :name")})
public class Menu implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "id", nullable = false)
    private Integer id;
    @Column(name = "name", nullable = false)
    private String name;

    public Menu() {
    }

    public Menu(Integer id) {
        this.id = id;
    }

    public Menu(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Menu)) {
            return false;
        }
        Menu other = (Menu) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "ec.Menu[id=" + id + "]";
    }
}

Und einen von mir gemachten Entity-Class-Manager (ECManager):
Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package cms;

import ec.Menu;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

/**
 *
 * @author adrian
 */
public class ECManager {
    private static ArrayList<Menu> menuList = new ArrayList<Menu>();
    
    @Resource
    private UserTransaction utx = null;
    @PersistenceUnit(unitName = "cmsPU")
    private EntityManagerFactory emf = null;
    
    public ECManager() {
    }
    
    public EntityManager getEntityManager() {
        return emf.createEntityManager(); // HIER TRITT DER FEHLER AUF!
    }
    
    public void create(Object obj) {
        EntityManager em = null;
        try {
            em = getEntityManager();
            utx.begin();
            em.persist(obj);
            utx.commit();
        } catch (RollbackException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicMixedException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicRollbackException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalStateException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NotSupportedException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SystemException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void edit(Object obj) {
        EntityManager em = getEntityManager();
        try {
            utx.begin();
//            obj = em.merge(obj);
            em.merge(obj);
            utx.commit();
        } catch (RollbackException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicMixedException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicRollbackException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalStateException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NotSupportedException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SystemException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void remove(Object obj) {
        EntityManager em = getEntityManager();
        try {
            utx.begin();
            em.remove(obj);
            utx.commit();
        } catch (RollbackException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicMixedException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicRollbackException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalStateException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NotSupportedException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SystemException ex) {
            Logger.getLogger(ECManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Nun Frage ich mich wieso beim Aufruf von emf.createEntityManager(); ein Fehler auftritt! Kann mir da einer weiterhelfen? Oder habe ich etwas vergessen? Die Entity-Classe habe ich automatisch in NetBeans von der Datenbank (MySql) generieren lassen. Die Persistence.xml ist auch vorhanden:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="cmsPU" transaction-type="JTA">
    <jta-data-source>MYSQL</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties/>
  </persistence-unit>
</persistence>

Danke für eure mögliche Hilfe.
 
Zum einen wäre es (wie immer) wichtig zu wissen, was für ein Fehler auftritt. Exception? Stacktrace?

Zum anderen sieht das ein wenig nach Kraut und Rüben aus. Dein ECManager braucht, soweit ich weiß, zumindest ein Interface und ein @Stateless, sonst bekommt der nix injected. Einen NamedQuery für das Auslesen per id brauchst du nicht, das geht per API auf dem Entitymanager (irgendwas wie get(id, Entity.class)). Transaktionen macht man im allgemeinen auch über Annotationen: @TransactionAttribute usw. Das Exceptionhandling könnte auch unterirdischer nicht sein. Die brauchst du - soweit ich das Überblick - alle nicht fangen. Desweiteren reicht ein statischer Logger für die Klasse.

Gruß
Ollie
 
Danke für deine Hilfe Oliver.

Ich hab nun folgende Klasse geschrieben, die mir eigentlich die Arbeit abnehmen soll:
Code:
package management;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class EntityClassManager {
    private EntityManagerFactory emf = null;
    private EntityManager em = null;

    public EntityClassManager() {
        emf = Persistence.createEntityManagerFactory("cmsPU");
        em = emf.createEntityManager();
        em.getTransaction().begin();
    }

    public void insert(Object obj) {
        em.persist(obj);
    }

    public void update(Object obj) {
        em.refresh(obj);
    }

    public void delete(Object obj) {
        em.remove(obj);
    }

    public void commit() {
        em.getTransaction().commit();
        em.close();
    }
}

Das Problem dabei ist, dass nicht das Objekt der klasse (zB. Menu m), sondern die tostring-Methode übergeben wird:

Code:
@Override
    public String toString() {
        return "entityclasses.Menu[id=" + id + "]";
    }

Hier noch der Code wie ich meinen EntityClassManager benutze:
Code:
Menu m = new Menu();
        m.setId(1);
        m.setName("Home");
        m.setSort(1);

        EntityClassManager ecm = new EntityClassManager();
        ecm.insert(m);
        ecm.commit();

Hier noch die Fehlermeldungen:
-> org.apache.jasper.JasperException: java.lang.IllegalArgumentException: Object: entityclasses.Menu[id=1] is not a known entity type.
-> java.lang.IllegalArgumentException: Object: entityclasses.Menu[id=1] is not a known entity type.

Ich hätte nun gerne gewusst, wie ich das hinkrieg, damit ich das Objekt ansich übertrage, und nicht die tostring-Methode.
 
Mehrere Sachen:

1. Was du da siehst ist die Logausgabe. Wie sollte er die auch erstellen OHNE toString zu rufen? ;) Die Exception sagt dir aber, das die Klasse Menu nicht in der PersistenceUnit zu finden ist. Wie sieht die persistence.xml aus?

2. Schau dir nochmal genau die Bedeutung der Methoden persist(), refresh(), merge() an... die kann man nicht so einfach auf insert update mappen.

3. Dir ist sicher aufgefallen, dass read Methoden völlig fehlen. Versuch die mal zu implementieren und du wirst merken, dass es nicht viel Sinn macht so eine KLasse zu implementieren.

Wenn du mit SessionBeans arbeitest ist es am sinnvollsten dort gleich den EntityManager injecten zu lassen. Transaktionen kannst du dann über @TransactionAttribute Transaktionsgrenzen definieren.

Ohne SessionBeans würde ich ein klassisches DAO Pattern bevorzugen, dass dann pro Entität entsprechende Methoden anbietet. Dein Helperentwurf ist halt so ein Hybrid aus beidem... ;)

Gruß
Ollie
 

Neue Beiträge

Zurück