# JPA - Datenbanktabellen auslesen



## mavinatic (11. Jul 2011)

Hallo Community,

ich habe eine Frage und zwar möchte ich aus meiner Oracle 10g XE alle Datenbanktabellen eines bestimmten Benutzters auslesen ;-) Ist das mit JPA irgendwie möglich?

Gruß

George


----------



## Peter W. Marth (12. Jul 2011)

Hallo,

es sollte möglich sein, mit JPA auf die Spalten OWNER und TABLE_NAME der View SYS.ALL_TABLES zu mappen und damit eine Abfrage auf einen bestimmten Owner zu formulieren.


----------



## mavinatic (12. Jul 2011)

Hallo ich bin ein extremer anfänger was jpa angeht und bitte darum es anfängerfreundlicher zu formulieren, vllt mit code beispiel 

gruß 

george


----------



## Peter W. Marth (13. Jul 2011)

Hallo,

ich hab mal vorausgesetzt, dass Du die Grundlagen von JPA kennst und dass als Persistence Provider für JPA Hibernate zum Einsatz kommt.

Zunächst braucht man eine Entity-Klasse, welche die View ALL_TABLES repräsentiert. Dabei müssen nicht alle Tabellenspalten dieser View gemappt werden, nur die für diesen zweck interessanten OWNER und TABLE_NAME:


```
package test;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity(name = "AllTables")
@Table(name = "SYS.ALL_TABLES")
public class AllTables {

	@Column(name = "OWNER")
	private String owner;
	@Id
	@Column(name = "TABLE_NAME")
	private String tableName;

	public AllTables() {
		super();
	}

	public AllTables(String owner, String tableName) {
		super();
		this.owner = owner;
		this.tableName = tableName;
	}

	public String getOwner() {
		return owner;
	}

	public void setOwner(String owner) {
		this.owner = owner;
	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

}
```

Dazu noch eine Persistence Unit, in der die Datenbank-Verbindungsparameter und die Entity-Klasse stehen:

[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="demo">

		<provider>org.hibernate.ejb.HibernatePersistence</provider>

		<class>test.AllTables</class>				

		<properties>
			<property name="hibernate.archive.autodetection" value="none"/>
			<property name="hibernate.show_sql" value="true"/>
			<property name="hibernate.format_sql" value="true"/>
			<property name="hibernate.c3p0.min_size" value="1"/>
			<property name="hibernate.c3p0.max_size" value="1"/>
			<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9iDialect"/>
            <property name="hibernate.connection.driver_class" 
                      value="oracle.jdbc.driver.OracleDriver" />
            <property name="hibernate.connection.url" 
                      value="jdbcracle:thinmeindatenbankserver:1521:meinedatenbank" />
            <property name="hibernate.connection.username" value="meinuser" />
            <property name="hibernate.connection.password" value="meinpasswort" />
		</properties>
	</persistence-unit>

</persistence>
[/XML]

Und dann noch eine Klasse, um das Ganze mal mit einer einfachen JPA-Abfrage zu testen:


```
package test;

import java.util.List;

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

public class QuickAndDirty {

	public static void main(String[] args) {
	    EntityManagerFactory emf;
	    EntityManager em;
        emf = Persistence.createEntityManagerFactory("demo");
        em = emf.createEntityManager();
        
        Query query = em.createQuery("SELECT a FROM AllTables a");
        @SuppressWarnings("unchecked")
		List<AllTables> resultList = query.getResultList();
        for(AllTables a:resultList){
        	System.out.println("name="+a.getTableName()+" owner="+a.getOwner());
        }
	}

}
```


----------



## mavinatic (13. Jul 2011)

Ich bedanke mich 

Das war sehr ausführlich, gibts evtl noch einen einfacheren weg außer extra EntityClass ?


----------



## Peter W. Marth (13. Jul 2011)

Natürlich lässt sich das noch anders ermitteln, aber dann nicht mit JPA. Man kann z.B. selber eine JDBC-Connection zur Datenbank aufbauen und dann eine Abfrage "select table_name, owner from sys.all_tables" absetzen, das ResultSet auswerten usw. Aber "einfacher" wird die Sache dadurch auch nicht wirklich.


----------



## mavinatic (13. Jul 2011)

Kann ich nicht einfach ein "NativeQuery" machen?


----------



## maki (13. Jul 2011)

mavinatic hat gesagt.:


> Kann ich nicht einfach ein "NativeQuery" machen?


Klar.


----------



## Peter W. Marth (13. Jul 2011)

Ja, stimmt, so geht's auch ohne Entity-Klasse:


```
Query q2 = em.createNativeQuery( "select owner, table_name from sys.all_tables" );
        List<Object[]> r2 = q2.getResultList();
        for(Object[] oa:r2){
            for(Object o:oa){
                String s = (String)o;
                System.out.println("s=" + s);
            }
        }
```


----------



## mavinatic (13. Jul 2011)

Ich bedanke mich nochmals und habe noch eine Frage:

Ich hab die Variable String databaseUser = "xy" und möchte die in den SQL-Query einbauen, es müsste folglich so aussehen:

"SELECT table_name, owner FROM sys.all_tables WHERE owner LIKE '"+databaseUser+"'"

aber dabei bekomm ich NICHTS zurück :/ Ich weiß 100%ig das dieser benutzer existiert ich benutze Oracle 10g XE


----------



## mavinatic (13. Jul 2011)

Ich habe jetzt nochmals probiert den Ansatz mit den Entitys, aber dann sagt er mir folgendes: 


```
org.hibernate.AnnotationException: No identifier specified for entity: ....
```

Nur zur Info!


----------



## Peter W. Marth (14. Jul 2011)

Die Abfrage arbeitet case sensitive, man muss dabei die Groß-/Kleinschreibung beachten. Mit z.B.

"SELECT table_name, owner FROM sys.all_tables WHERE lower(owner) = lower('"+databaseUser+"')"
oder
"SELECT table_name, owner FROM sys.all_tables WHERE lower(owner) LIKE lower('%"+databaseUser+"%')"

kann das "normalisiert" werden.




> org.hibernate.AnnotationException: No identifier specified for entity: ....



Der Trick besteht darin, einfach eine Spalte mit @Id zu annotieren, um JPA einen Primary Key vorzugaukeln.


----------



## mavinatic (14. Jul 2011)

Aber ich habe doch garkeinen PrimaryKey auf welche spalte soll ich folglich die Id-Annotation setzen? Oder sind die Datenbanktabellennamen PK?


----------



## Peter W. Marth (14. Jul 2011)

Es spielt für diesen Fall keine Rolle, welche Spalte mit @Id annotiert wird, da nur lesend auf die View zugegriffen wird. der Trick dient nur dazu, JPA/Hibernate zufrieden zu stellen.


----------



## mavinatic (14. Jul 2011)

Okay Stimmt, das hatte ich vergessen, dann bedanke ich mich!!! Hat mir SEHR weitergeholfen


----------

