# JPA Derby primary key wird nicht automatisch generiert



## Merschi (8. April 2008)

Hallo,

wenn ich eine Entity Klasse mit .persist speichern möchte, erhalte ich folgende Fehlermeldung. Dabei möchte ich, dass der Primary Key automatisch von Derby generiert wird.

*org.apache.jasper.JasperException: java.lang.IllegalArgumentException: Object: Entity.Newentity[id=null] is not a known entity type.*

Die Tablle in Derby habe ich so angelegt:


```
CREATE TABLE NEWENTITY
    (ID SMALLINT NOT NULL PRIMARY KEY GENERATED always AS IDENTITY 
	(START WITH 2, INCREMENT BY 1),
    firstname VARCHAR(100));
```

Die Entity Klasse:


```
@Entity
@Table(name = "NEWENTITY")
@NamedQueries({@NamedQuery(name = "Newentity.findById", query = "SELECT n FROM Newentity n WHERE n.id = :id"), @NamedQuery(name = "Newentity.findByFirstname", query = "SELECT n FROM Newentity n WHERE n.firstname = :firstname")})
public class Newentity implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "ID", nullable = false)
    private Long id;
    @Column(name = "FIRSTNAME")
    private String firstname;

    public Newentity() {
    }

    public Newentity(Long id) {
        this.id = id;
    }

    public Long getId() {
        return id;
    }

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

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

}
```

Der Aufruf von Persist:


```
public void createNewEntity() {
        Newentity en = new Newentity();
        //en.setId(10L);
        en.setFirstname("name1");
        
        EntityManager em = getEMF().createEntityManager();
        
            try {
                em.getTransaction().begin();
                em.merge(en);
                //em.flush();
                //em.clear();
                em.getTransaction().commit();
            } finally {
                em.close();
            }
        
    }
```

Ich habe schon mehrere Versionen von @GeneratedValue... ausprobiert aber ich verstehe einfach nicht warum ich die Entity Klasse nicht persistieren kann und der Primary Key automatisch generiert wird.

Wenn ich per SQL einen insert in folgender From durchführe, werden die Daten sätze gespeichert und der PK wird auch 'unique auto' generiert.


```
INSERT INTO newentity VALUES (DEFAULT,'Michael');
```

Ich habe mir das so vorgestellt, dass ich die "ID" gar nicht setzen muss.

Vielleicht ist noch wichtig was ich so verwende:

- Netbeans 6
- Glassfish
- Toplink
- Derby

Wäre nett, wenn mir jemand helfen könnte.


----------



## Oliver Gierke (8. April 2008)

Ich würde mit weniger Annotationen anfangen und das SQL für die Tabellen vom Persistenceprovider generieren lassen. Sonst kommt man schnell in Teufels Küche. nullable = false ist zum Beispiel obsolet, eigentlich das komplette @Column. Desweiteren würde ich - wenn es keine dedizierten Gründe für was anderes gibt, mit GenerationType.AUTO anfangen und schauen, was sich da tut.

Desweiteren ist em.persist(..) wohl die richtigere Wahl um ein neues Objekt zu persistieren.

Gruß
Ollie


----------



## Merschi (8. April 2008)

Hallo Ollie,

nochmals vielen Dank, für die schnelle Antwort. 

Für alle anderen, die dieses Problem haben:

Im Post http://www.tutorials.de/forum/enter...by-drop-create-tables-funktioniert-nicht.html

Hatte ich mein Problem geschildert, das "drop-and-create-tables" nicht funktionierte.
es fehlte in der persitence.xml folgender eintrag:

*<property name="toplink.ddl-generation.output-mode" value="both"/>*

Komplette Perstitence.xml:


```
<?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="KeyGenPU" transaction-type="JTA">
    <provider>oracle.toplink.essentials.PersistenceProvider</provider>
    <jta-data-source>jdbc/sample</jta-data-source>
    <class>Entity.Newentity</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="toplink.ddl-generation.output-mode" value="both"/>
      <property name="toplink.ddl-generation" value="drop-and-create-tables"/>
   </properties>
  </persistence-unit>
</persistence>
```

Meine Entity Klasse sieht jetzt so aus:


```
@Entity
@Table(name = "NEWENTITY")
@NamedQueries({@NamedQuery(name = "Newentity.findById", query = "SELECT n FROM Newentity n WHERE n.id = :id"), @NamedQuery(name = "Newentity.findByFirstname", query = "SELECT n FROM Newentity n WHERE n.firstname = :firstname")})
public class Newentity implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
    private String firstname;

    public Newentity() {
    }

    public Newentity(Long id) {
        this.id = id;
    }

    public Long getId() {
        return id;
    }

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

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }
}
```

Ist @Column wirklich veraltet? Denn im reference Tutorial wird es empfohlen. Es ist schon ziemlich verwirrend wenn man sich nicht an die Referenz halten kann.

Gruss

Merschi


----------



## Oliver Gierke (8. April 2008)

Nicht veraltet, obsolete - also nicht notwendig, da deine Id Spalte automatisch nullable = false wird und die meisten JPA Provider Klassenmember in Großbuchstaben als Spaltennamen verwenden. Also schlicht nicht notwendig.

Gruß
Ollie


----------

