Hibernate - DB View aufrufen

y0dA

Erfahrenes Mitglied
Hoi!

Ich muss auf eine Datenbank View zugreifen um an bestimmte Daten zu kommen, wie soll ich jene aufrufen? Soll ich einfach eine Query machen oder kann man eine View wie eine Table behandeln oder gibt es eine Hibernate Lösung dafür?

mfg
 
hm,

für mich ist eine view eine logische relation, welche durch eine gespeicherte abfrage definiert ist, und bei jedem zugriff wird die view zuerst neu erzeugt

hibernate bietet die möglichkeit, abfragen auf tabellen loszujagen, genau so auch auf views, diese sind ja mehr oder weniger nur tabellen wo das ergebnis einer abfrage liegt


wenn du die view nur als zwischenspeicher für ein abfrage hast (was ich als view bezeichne) dann könntest du die abfrage ja direkt mit hibernate laufen lassen auf die ausgangstabelle und sparst dir den zwischenschritt über die view

eine view ist nicht mehr als eine tabelle, und darum kannst mit hibernate auch abfragen loslassen, nur wenn die view keine objekte einer deiner definierten / persistierten klassen beinhaltet, dann kanns umständlich werden mit den abfragen
 
Zuletzt bearbeitet:
Hallo,

Ich muss auf eine Datenbank View zugreifen um an bestimmte Daten zu kommen, wie soll ich jene aufrufen? Soll ich einfach eine Query machen oder kann man eine View wie eine Table behandeln oder gibt es eine Hibernate Lösung dafür?
Du kannst eine View in Hibernate wie eine Tabelle behandeln... allerdings erstmal nur read-only. Wenn du auch inserts / delete-operation erlauben möchtest, dann musst du auf Datenbankseite entsprechende Trigger formulieren.

für mich ist eine view eine logische relation, welche durch eine gespeicherte abfrage definiert ist, und bei jedem zugriff wird die view zuerst neu erzeugt
... schon mal was von Materialized Views gehört?



Gruß Tom
 
Also irgendetwas klappt da nicht, bekomme folgende Exception:
Code:
org.hibernate.hql.ast.QuerySyntaxException: V_STANDORT_PORTAL is not mapped [ FROM V_STANDORT_PORTAL WHERE E_30019_DBK =  '301920000630141504440001' AND V_STANDORT_PORTAL.ANZAHL > 0]

db klasse snippet:
Code:
	public static ArrayList<LocationPortalModel> loadLocation(final String dbk) {
		/* create statement */
		StringBuilder sb = new StringBuilder();
		sb.append(" FROM ");
		sb.append(LocationPortalDB.VIEW_NAME);
		sb.append(" WHERE ");
		sb.append(LocationPortalDB.DBK_TABLE);
		sb.append(" =  '");
		sb.append(dbk);
		sb.append("'");
		sb.append(" AND ");
		sb.append(LocationPortalDB.COLUMN_3);
		sb.append(" > 0");
		
		Session session = HibernateUtil.getCurrentSession();
		Transaction tx = null;
		ArrayList<LocationPortalModel> values = null;
		
		try {
			tx = session.beginTransaction();
			
			/* load data */
			values = (ArrayList<LocationPortalModel>) session.createQuery(sb.toString()).list();	
			
			/* commit and close session */
			tx.commit();	
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			session = null;
			tx = null;
		}
		return values;
	}

konstanten dazu.
Code:
               private static final String VIEW_NAME = "V_STANDORT_PORTAL";

	private static final String DBK_TABLE = "E_30019_DBK";

	private static final String COLUMN_1 = "DBK";

	private static final String TABLE_1 = "E_30019";

	private static final String COLUMN_2 = "ORT";

	private static final String COLUMN_3 = "V_STANDORT_PORTAL.ANZAHL";

	private static final String ORDER_BY_COLUMNS = "BEZIRK, GEMEINDE_NR, PLZ,ORT,ADR";

model:
Code:
public class LocationPortalModel {
	private String district;
	
	/** borough number */
	private Integer boroughNumber;
	
	/** borough description */
	private String boroughDescription;
	
	/** collector localtiy */
	private Integer collectorLocaltity;
	
	/** locality number */
	private Integer localityNumber;
	
	/** address */
	private String address;
	
	/** zip code */
	private Integer zip;
	
	/** locality */
	private String locality;
	
	/** case type */
	private String caseType;
	
	/** case count */
	private Integer count;
	
	/** case quality sort */
	private String qualityKind;
	
	/** dbk from E_30019 */
	private String dbk;
	
	/** geo mercato coordiante x */
	private Integer geoMercX;
	
	/** geo mercato coordiante y */
	private Integer geoMercY;
	
	/** quality of the geo data */
	private Integer geoQuality;

	/**
	 * empty constructor
	 */
	public LocationPortalModel() {
		// nothing to do
	}

	public LocationPortalModel(final String district, final Integer boroughNumber, final String boroughDescription,
			final Integer collectorLocaltity, final Integer localityNumber, final String address, final Integer zip,
			final String locality, final String caseType, final Integer count, final String qualityKind,
			final String dbk, final Integer geoMercX, final Integer geoMercY, final Integer geoQuality) {
		this.district = district;
		this.boroughNumber = boroughNumber;
		this.boroughDescription = boroughDescription;
		this.collectorLocaltity = collectorLocaltity;
		this.localityNumber = localityNumber;
		this.address = address;
		this.zip = zip;
		this.locality = locality;
		this.caseType = caseType;
		this.count = count;
		this.qualityKind = qualityKind;
		this.dbk = dbk;
		this.geoMercX = geoMercX;
		this.geoMercY = geoMercY;
		this.geoQuality = geoQuality;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getBoroughDescription() {
		return boroughDescription;
	}

	public void setBoroughDescription(String boroughDescription) {
		this.boroughDescription = boroughDescription;
	}

	public Integer getBoroughNumber() {
		return boroughNumber;
	}

	public void setBoroughNumber(Integer boroughNumber) {
		this.boroughNumber = boroughNumber;
	}

	public String getCaseType() {
		return caseType;
	}

	public void setCaseType(String caseType) {
		this.caseType = caseType;
	}

	public Integer getCollectorLocaltity() {
		return collectorLocaltity;
	}

	public void setCollectorLocaltity(Integer collectorLocaltity) {
		this.collectorLocaltity = collectorLocaltity;
	}

	public Integer getCount() {
		return count;
	}

	public void setCount(Integer count) {
		this.count = count;
	}

	public String getDbk() {
		return dbk;
	}

	public void setDbk(String dbk) {
		this.dbk = dbk;
	}

	public String getDistrict() {
		return district;
	}

	public void setDistrict(String district) {
		this.district = district;
	}

	public String getLocality() {
		return locality;
	}

	public void setLocality(String locality) {
		this.locality = locality;
	}

	public Integer getLocalityNumber() {
		return localityNumber;
	}

	public void setLocalityNumber(Integer localityNumber) {
		this.localityNumber = localityNumber;
	}

	public String getQualityKind() {
		return qualityKind;
	}

	public void setQualityKind(String qualityKind) {
		this.qualityKind = qualityKind;
	}

	public Integer getZip() {
		return zip;
	}

	public void setZip(Integer zip) {
		this.zip = zip;
	}

	public Integer getGeoMercX() {
		return geoMercX;
	}

	public void setGeoMercX(Integer geoMercX) {
		this.geoMercX = geoMercX;
	}

	public Integer getGeoMercY() {
		return geoMercY;
	}

	public void setGeoMercY(Integer geoMercY) {
		this.geoMercY = geoMercY;
	}

	public Integer getGeoQuality() {
		return geoQuality;
	}

	public void setGeoQuality(Integer geoQuality) {
		this.geoQuality = geoQuality;
	}	
}

mapping:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="at.pcd.wam.technologie.persistence.model">
  <class name="at.pcd.wam.technologie.persistence.model.LocationPortalModel" table="V_STANDORT_PORTAL" >
 	<!-- primary key -->
  	<id name="dbk" type="string" column="E_30019_DBK">
  	<generator class="assigned"></generator>
  	</id>  	

	<!-- <property name="dbk" type="string" column="E_30019_DBK"></property> -->
	<property name="district" type="string" column="BEZIRK"></property>
	<property name="boroughNumber" type="integer" column="GEMEINDE_NR"></property>
	<property name="boroughDescription" type="string" column="GEMEINDE_BEZ"></property>
	<property name="collectorLocaltity" type="integer" column="SAMMLER_STANDORT"></property>
	<property name="localityNumber" type="integer" column="STANDORT"></property>
	<property name="address" type="string" column="ADR"></property>
	<property name="zip" type="integer" column="PLZ"></property>
	<property name="locality" type="string" column="ORT"></property>
	<property name="caseType" type="string" column="BEH_TYP"></property>
	<property name="count" type="integer" column="ANZAHL"></property>
	<property name="qualityKind" type="string" column="QSORTE"></property>
	<property name="geoMercX" type="integer" column="GEO_MERC_X"></property>
	<property name="geoMercY" type="integer" column="GEO_MERC_Y"></property>
	<property name="geoQuality" type="integer" column="GEO_QUALITY"></property>

  </class>
</hibernate-mapping>

Das Problem ist zu einem dass die View keinen Primary Key besitzt aber das hbm einen verlangt.
Zweitens funktioniert die Query:
Code:
	values = (ArrayList<LocationPortalModel>) session.createSQLQuery(sb.toString()).list();
Liefert mir aber Objects und kein Model (query mit "select * from")
Und eben bei "createQuery" schreibt er die Exception von oben.
 
Zuletzt bearbeitet:
Ist kein orig. Code sonder ein dummy versuch, jedoch hilft mir deine Antwort nicht wirklich weiter, zumal du meinstest ich könnte eine View genauso behandeln wie eine Tabelle. :(
 
Hallo,

Ist kein orig. Code sonder ein dummy versuch, jedoch hilft mir deine Antwort nicht wirklich weiter, zumal du meinstest ich könnte eine View genauso behandeln wie eine Tabelle. :(
Trotzdem stehen da einige Infos zu deiner Firma drin, aber mir solls egal sein...

Du kannst mit Views genauso arbeiten wie mit Tabellen mit der Ausnahme das diese Standardmäßig nur read-only sind... wenn du keine entsprechenden Trigger definierst etc.
Hab ich alles schon gemacht und funktioniert wunderbar. Du hast da noch irgend ein Problem in deinem Mapping...

Aus der Hibernate Doku:
There is no difference between a view and a base table for a Hibernate mapping, as expected this is transparent at the database level (note that some DBMS don't support views properly, especially with updates). Sometimes you want to use a view, but can't create one in the database (ie. with a legacy schema). In this case, you can map an immutable and read-only entity to a given SQL subselect expression:
http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#mapping-declaration-class

Gruß Tom
 
Hmm und welches?

Hier mal der "neue" code:

Model:
Code:
public class LocationPortalModel {

	/** district */
	private String district;
	
	/** borough number */
	private Integer boroughNumber;
	
	/** borough description */
	private String boroughDescription;
	
	/** collector localtiy */
	private Integer collectorLocaltity;
	
	/** locality number */
	private Integer localityNumber;
	
	/** address */
	private String address;
	
	/** zip code */
	private Integer zip;
	
	/** locality */
	private String locality;
	
	/** case type */
	private String caseType;
	
	/** case count */
	private Integer count;
	
	/** case quality sort */
	private String qualityKind;
	
	/** dbk from E_30019 */
	private String dbk;
	
	/** geo mercato coordiante x */
	private Integer geoMercX;
	
	/** geo mercato coordiante y */
	private Integer geoMercY;
	
	/** quality of the geo data */
	private Integer geoQuality;
	
	/** dbk from E_30021 */
	private String id;

	public LocationPortalModel() {
		// nothing to do
	}

	public LocationPortalModel(final String district, final Integer boroughNumber, final String boroughDescription,
			final Integer collectorLocaltity, final Integer localityNumber, final String address, final Integer zip,
			final String locality, final String caseType, final Integer count, final String qualityKind,
			final String dbk, final Integer geoMercX, final Integer geoMercY, final Integer geoQuality,
			final String id) {
		this.district = district;
		this.boroughNumber = boroughNumber;
		this.boroughDescription = boroughDescription;
		this.collectorLocaltity = collectorLocaltity;
		this.localityNumber = localityNumber;
		this.address = address;
		this.zip = zip;
		this.locality = locality;
		this.caseType = caseType;
		this.count = count;
		this.qualityKind = qualityKind;
		this.dbk = dbk;
		this.geoMercX = geoMercX;
		this.geoMercY = geoMercY;
		this.geoQuality = geoQuality;
		this.id = id;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getBoroughDescription() {
		return boroughDescription;
	}

	public void setBoroughDescription(String boroughDescription) {
		this.boroughDescription = boroughDescription;
	}

	public Integer getBoroughNumber() {
		return boroughNumber;
	}

	public void setBoroughNumber(Integer boroughNumber) {
		this.boroughNumber = boroughNumber;
	}

	public String getCaseType() {
		return caseType;
	}

	public void setCaseType(String caseType) {
		this.caseType = caseType;
	}

	public Integer getCollectorLocaltity() {
		return collectorLocaltity;
	}

	public void setCollectorLocaltity(Integer collectorLocaltity) {
		this.collectorLocaltity = collectorLocaltity;
	}

	public Integer getCount() {
		return count;
	}

	public void setCount(Integer count) {
		this.count = count;
	}

	public String getDbk() {
		return dbk;
	}

	public void setDbk(String dbk) {
		this.dbk = dbk;
	}

	public String getDistrict() {
		return district;
	}

	public void setDistrict(String district) {
		this.district = district;
	}

	public String getLocality() {
		return locality;
	}

	public void setLocality(String locality) {
		this.locality = locality;
	}

	public Integer getLocalityNumber() {
		return localityNumber;
	}

	public void setLocalityNumber(Integer localityNumber) {
		this.localityNumber = localityNumber;
	}

	public String getQualityKind() {
		return qualityKind;
	}

	public void setQualityKind(String qualityKind) {
		this.qualityKind = qualityKind;
	}

	public Integer getZip() {
		return zip;
	}

	public void setZip(Integer zip) {
		this.zip = zip;
	}

	public Integer getGeoMercX() {
		return geoMercX;
	}

	public void setGeoMercX(Integer geoMercX) {
		this.geoMercX = geoMercX;
	}

	public Integer getGeoMercY() {
		return geoMercY;
	}

	public void setGeoMercY(Integer geoMercY) {
		this.geoMercY = geoMercY;
	}

	public Integer getGeoQuality() {
		return geoQuality;
	}

	public void setGeoQuality(Integer geoQuality) {
		this.geoQuality = geoQuality;
	}

	public String getId() {
		return id;
	}

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

Mapping dazu:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="at.pcd.wam.technologie.persistence.model">
  <class name="at.pcd.wam.technologie.persistence.model.LocationPortalModel" table="V_STANDORT_PORTAL" >
 	<!-- primary key -->
  	<id name="id" type="string" column="E_30021_DBK">
  	<generator class="assigned"></generator>
  	</id>  	

	<property name="dbk" type="string" column="E_30019_DBK"></property>
	<property name="district" type="string" column="BEZIRK"></property>
	<property name="boroughNumber" type="integer" column="GEMEINDE_NR"></property>
	<property name="boroughDescription" type="string" column="GEMEINDE_BEZ"></property>
	<property name="collectorLocaltity" type="integer" column="SAMMLER_STANDORT"></property>
	<property name="localityNumber" type="integer" column="STANDORT"></property>
	<property name="address" type="string" column="ADR"></property>
	<property name="zip" type="integer" column="PLZ"></property>
	<property name="locality" type="string" column="ORT"></property>
	<property name="caseType" type="string" column="BEH_TYP"></property>
	<property name="count" type="integer" column="ANZAHL"></property>
	<property name="qualityKind" type="string" column="QSORTE"></property>
	<property name="geoMercX" type="integer" column="GEO_MERC_X"></property>
	<property name="geoMercY" type="integer" column="GEO_MERC_Y"></property>
	<property name="geoQuality" type="integer" column="GEO_QUALITY"></property>

  </class>
</hibernate-mapping>

query:
Code:
StringBuilder sb = new StringBuilder();
		sb.append("FROM LocationPortalModel");
		
		
		Session session = HibernateUtil.getCurrentSession();
		Transaction tx = null;
		ArrayList<LocationPortalModel> values = null;
		try {
			tx = session.beginTransaction();
			
			/* load data */
			values = (ArrayList<LocationPortalModel>) session.createQuery(sb.toString()).list();	
//			values = (ArrayList<LocationPortalModel>) session.createSQLQuery(sb.toString()).list();	

			tx.commit();

1. Wie soll man den primärschlüssel versorgen wenn die View keinen besitzt?
2. im mapping file: table=view_name?

WEnn ich die Query von oben ausführe bekomme ich die ausfürhliche meldung:
Code:
org.hibernate.exception.SQLGrammarException: could not execute query
sehr aussagekräftig..
 
Zuletzt bearbeitet:
Mittlerweile bin ich auf kleinere Fehler gestossen und habe sie behoben nun bekomme ich folgendes:
Code:
java.sql.SQLException: Konvertierung zu interner Darstellung nicht erfolgreich

Und hierbei steh ich nun an, da die View Felder nur varchar sowie number Felder sind.
varchar = string
number = double ?

**EDIT**
query, also steht in sb:
Code:
 SELECT * FROM V_STANDORT_PORTAL WHERE E_30019_DBK =  '301920000630141504440001' AND V_STANDORT_PORTAL.ANZAHL > 0

so funktioniert es, jedoch bekomme ich "Ljava.lang.Object" zurück und mit denen kann ich auch nichts machen, da ClassCastExceptions folgen wenn ich versuche die zu casten.
Code:
values = (ArrayList<LocationPortalModel>) session.createSQLQuery(sb.toString()).list();

so passiert überhaupt nix, sprich er arbeitet unendlich bis ich ihn abbreche...
Code:
values = (ArrayList<LocationPortalModel>) session.createQuery(sb.toString()).list();
 
Zuletzt bearbeitet:
Zurück