Warum ist die Transaction not active?

Hallo,

dank eurer Hilfe habe ein Problem schon lösen können.

Ich habe folgende Klasse geschrieben, die Datensätze aus zwei Files lesen und mit Hibernate in die Datenbank einfügen soll.

Java:
package core;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

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

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import entity.Article;
import entity.Demand;

public class FileImporter {
	

	public void read() throws IOException, ParseException {
		FileReader file;
		String line = "";
		ArrayList<String> artNum = new ArrayList<String>();
		ArrayList<String> artName = new ArrayList<String>();
		ArrayList<Date> artDate = new ArrayList<Date>();
		try {
			file = new FileReader("C:/Daten/Datei.TXT");
			BufferedReader reader = new BufferedReader(file);
			int counter = 0;
			while ((line = reader.readLine()) != null) {
				counter++;
				if (counter > 6) {
					String[] sep = line.split("[|]");
					if (sep[13].trim().startsWith("000")) 
					{
						
						artNum.add(sep[13].trim());
						artName.add(sep[14].trim());					
						
						String dateString = sep[10].trim();
						String dateFormatString = "dd.MM.yyyy";
						SimpleDateFormat format = new SimpleDateFormat(dateFormatString);
						Date newDate = format.parse(dateString);
						artDate.add(newDate);
					}
				}
			}
			
			
		} catch (FileNotFoundException e) {
			throw new RuntimeException("File not found");
		} catch (IOException e) {
			throw new RuntimeException("IO Error occured");
		}

		File inputWorkbookAlleMarken = new File("C:/Daten/Daten.xls");
		Workbook w;

		ArrayList<String> artikelNrList = new ArrayList<String>();
		ArrayList<String> abcList = new ArrayList<String>();
		ArrayList<String> xyzList = new ArrayList<String>();

		try {
			w = Workbook.getWorkbook(inputWorkbookAlleMarken);
			// Get the first sheet
			Sheet sheet = w.getSheet(0);
			Cell[] artikelNrCell = sheet.getColumn(0);
			
			for (int i = 2; i < sheet.getRows(); i++) {
				artikelNrList.add(artikelNrCell[i].getContents());
			}

			Cell[] abcCell = sheet.getColumn(16);
			for (int i = 2; i < sheet.getRows(); i++)
				abcList.add(abcCell[i].getContents());

			Cell[] xyzCell = sheet.getColumn(17);
			for (int i = 2; i < sheet.getRows(); i++)
				xyzList.add(xyzCell[i].getContents());

		} catch (BiffException e) {
			e.printStackTrace();
		}

		EntityManagerFactory emf = Persistence
				.createEntityManagerFactory("entityunit");
		EntityManager em = emf.createEntityManager();
		EntityTransaction tx = em.getTransaction();

		Article a;
		Demand d;

		for (int i = 0; i < artNum.size(); i++) {
			a = new Article();
			for (int j = 0; j < artikelNrList.size(); j++) {
				if (artNum.get(i).substring(0, 11).equals(artikelNrList.get(j))) {
					a.setNumber(artNum.get(i));
					a.setName(artName.get(i));
					a.setAbc(abcList.get(j));
					a.setXyz(xyzList.get(j));
					a = em.merge(a);
					
					d = new Demand();
					d.setArticle(a);
					d.setTimeStamp(artDate.get(i));
					
					d = em.merge(d);
					
					tx.commit();
				}
			}
		}
		em.close();
	}

	public static void main(String[] args) throws IOException, ParseException {
		FileImporter test = new FileImporter();
		test.read();
	}
}

Ich bekomme folgende Exception:

Code:
INFO: HHH000046: Connection properties: {user=postgres, password=****, autocommit=true, release_mode=auto}
28.10.2011 10:29:17 org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
28.10.2011 10:29:17 org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
28.10.2011 10:29:17 org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory
28.10.2011 10:29:17 org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
28.10.2011 10:29:18 org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000228: Running hbm2ddl schema update
28.10.2011 10:29:18 org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000102: Fetching database metadata
28.10.2011 10:29:18 org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000396: Updating schema
28.10.2011 10:29:18 org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000261: Table found: public.article
28.10.2011 10:29:18 org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000037: Columns: [id, abc, name, number, xyz, version]
28.10.2011 10:29:18 org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000108: Foreign keys: []
28.10.2011 10:29:18 org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000126: Indexes: [article_pkey, article_number_key]
28.10.2011 10:29:18 org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000261: Table found: public.demand
28.10.2011 10:29:18 org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000037: Columns: [timestamp, id, article_id, quantity, version]
28.10.2011 10:29:18 org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000108: Foreign keys: [fk79cbd66bd895becf]
28.10.2011 10:29:18 org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000126: Indexes: [demand_pkey]
28.10.2011 10:29:18 org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000232: Schema update complete
Hibernate: 
    select
        nextval ('hibernate_sequence')
Hibernate: 
    select
        nextval ('hibernate_sequence')
Exception in thread "main" java.lang.IllegalStateException: Transaction not active
	at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:66)
	at core.FileImporter.read(FileImporter.java:127)
	at core.FileImporter.main(FileImporter.java:135)

Ich verstehe nicht, warum. Wenn ich folgendes versuche, funktioniert es einwandfrei:

Java:
import java.util.Calendar;

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

import entity.Article;
import entity.Demand;

public class Test {

	public static void main(String[] args) {

		EntityManagerFactory emf = Persistence.createEntityManagerFactory("entityunit");

		
		EntityManager em = emf.createEntityManager();
		EntityTransaction tx = em.getTransaction();
		
		tx.begin();
		
		Article a1 = new Article();
		a1.setName("Hallo");
		a1.setNumber("1233");
		a1.setXyz("xyz");
		a1.setAbc("abc");
		
		a1 = em.merge(a1);
		
		Demand d = new Demand();

		d.setArticle(a1);
		
		Calendar cal = Calendar.getInstance();
		d.setTimeStamp(cal.getTime());
		
		em.merge(d);
		tx.commit();

		em.close();

	}

}

Code:
Hibernate: 
    select
        nextval ('hibernate_sequence')
Hibernate: 
    select
        nextval ('hibernate_sequence')
Hibernate: 
    insert 
    into
        Article
        (version, abc, name, number, xyz, id) 
    values
        (?, ?, ?, ?, ?, ?)
Hibernate: 
    insert 
    into
        Demand
        (version, article_id, quantity, timeStamp, id) 
    values
        (?, ?, ?, ?, ?)

Könntet ihr mir wieder helfen? :)
 
S

SlaterB

Gast
jede Transaktion kannst du nur einmal committen, danach musst du glaube ich eine neue aufmachen,
logge doch durch System.out.println() ob das erste commit() noch klappt, das zweite aber nicht mehr

oder sollte das commit() nicht eher nach der Schleife stehen?
 
Hi SlaterB,

das hat leider nicht funktioniert. Auch wenn ich es so versuche, bekomme ich dieselbe Exception:

Java:
for (int i = 0; i < artNum.size(); i++) {
			for (int j = 0; j < artikelNrList.size(); j++) {
				if (artNum.get(i).substring(0, 11).equals(artikelNrList.get(j))) {
					EntityManagerFactory emf = Persistence
							.createEntityManagerFactory("entityunit");
					EntityManager em = emf.createEntityManager();
					EntityTransaction tx = em.getTransaction();
					Article a;
					Demand d;
					a = new Article();
					a.setNumber(artNum.get(i));
					a.setName(artName.get(i));
					a.setAbc(abcList.get(j));
					a.setXyz(xyzList.get(j));
					a = em.merge(a);
					
					d = new Demand();
					d.setArticle(a);
					d.setTimeStamp(artDate.get(i));
					
					d = em.merge(d);
					
					tx.commit();
				}
			}
		}
 
S

SlaterB

Gast
ok, da hatte ich etwas übersehen, jetzt wo die Schleife keine Rolle mehr spielt kann ich aber sagen:
weil dieser Code nicht mit der funktionierenden Variante übereinstimmt,
vergleiche Punkt für Punkt was mit tx jeweils passiert, welche Methoden aufgerufen werden,
keine Angst, sind nur wenige, in der funktionierenden Variante eine mehr
 
Hi,

ich bräuchte nochmal eure Hilfe.
Die Spalte der Tabelle Artikel (Entity Artikel.java) ist
Code:
@Column(nullable = false, unique = true)
:

Java:
@Entity
public class Article extends ... {
	...
	@Column(nullable = false, unique = true)
	private String number;
...
}

Daher muss ich prüfen, ob in der Tabelle Artikel in der DB schon ein Artikel mit der Artikelnummer, die aus dem File gelesen wird, existiert. Wenn ein solcher Artikel bereits vorhanden ist, so soll er lediglich in die Tabelle Demand diesen neuen Artikel mit den entsprechenden Spalten einfügen.

Java:
@Entity
public class Demand extends ... {
...
	@ManyToOne(optional = false)
	private Article article;

...

}

Falls der Artikel noch nicht in der Datenbank vorhanden ist, so soll er einen neuen Artikel einlegen und wiederum die Demand-Tabelle auch dementsprechend ergänzen.

Dazu habe ich mir folgendes überlegt:

Java:
 EntityManagerFactory emf = Persistence
                .createEntityManagerFactory("entityunit");
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        for (int i = 0; i < artNum.size(); i++) {
        	
            for (int j = 0; j < artikelNrList.size(); j++) {
            	String qlString = "select a from Article a where a.number IN :number"; 
                Query q = em.createQuery(qlString);
                q.setParameter("number", artNum.get(i));
                Article actual = (Article) q.getSingleResult();
                if(actual.getNumber() == artNum.get(i))
                {
                	Demand d = new Demand();
                	d.setArticle(actual);
                	d.setQuantity(artQuantity.get(i));
                	d.setTimeStamp(artDate.get(i));
                	d.setPrice(artPrice.get(i));
                }
                else 
                {
                	Article a = new Article();
                	a.setAbc(abcList.get(j));
                	a.setXyz(xyzList.get(j));
                	a.setName(artName.get(i));
                	a.setNumber(artNum.get(i));
                	
                	Demand d = new Demand();
                	d.setArticle(actual);
                	d.setQuantity(artQuantity.get(i));
                	d.setTimeStamp(artDate.get(i));
                	d.setPrice(artPrice.get(i));
                }
            }
        }
        
        tx.commit();
        em.close();

Aber das funktioniert so scheinbar nicht. Ich bekomme folgende Exception:

Code:
Exception in thread "main" javax.persistence.NoResultException: No entity found for query
	at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:286)
	at core.FileImporter.read(FileImporter.java:109)
	at core.FileImporter.main(FileImporter.java:141)

Was die Exception mir sagt, ist mir klar. Daher habe ich es mit einer
Java:
getResultList()
versucht:

Java:
EntityManagerFactory emf = Persistence
                .createEntityManagerFactory("entityunit");
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        for (int i = 0; i < artNum.size(); i++) {
        	
            for (int j = 0; j < artikelNrList.size(); j++) {
            	String qlString = "select a from Article a where a.number IN :number"; 
                Query q = em.createQuery(qlString);
                q.setParameter("number", artNum.get(i));
                List<Article> actual = (List<Article>) q.getResultList();
                if(actual.get(i).getNumber() == artNum.get(i))
                {
                	Demand d = new Demand();
                	d.setArticle(actual.get(i));
                	d.setQuantity(artQuantity.get(i));
                	d.setTimeStamp(artDate.get(i));
                	d.setPrice(artPrice.get(i));
                }
                else 
                {
                	Article a = new Article();
                	a.setAbc(abcList.get(j));
                	a.setXyz(xyzList.get(j));
                	a.setName(artName.get(i));
                	a.setNumber(artNum.get(i));
                	
                	Demand d = new Demand();
                	d.setArticle(actual.get(i));
                	d.setQuantity(artQuantity.get(i));
                	d.setTimeStamp(artDate.get(i));
                	d.setPrice(artPrice.get(i));
                }
            }
        }
        
        tx.commit();
        em.close();

Hier kommt das raus:

Code:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
	at java.util.ArrayList.rangeCheck(ArrayList.java:604)
	at java.util.ArrayList.get(ArrayList.java:382)
	at core.FileImporter.read(FileImporter.java:110)
	at core.FileImporter.main(FileImporter.java:141)

Beides funktioniert so wohl auch nicht, wie ich mir das überlegt habe. Wie kann ich meine obigen Erläuterungen programmieren?

Danke euch.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Transaction / Session Problem Data Tier 4

Ähnliche Java Themen

Neue Themen


Oben