Kleines Beispiel zu JPA mit Spring 3.x, Hibernate 3.x, Lombok ,JUnit 4 und Maven 2.x

Hallo ich krame jetzt mal dein Posting raus. Habe irgendwie Probleme.

Ich habe dein Projekt als Maven Projekt importiert.
lombok.jar hab ich "Java Build Path" entfernt und die JAR über Maven import
Code:
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.12.2</version>
    </dependency>

Desweiteren werden Fehler angezeigt
Code:
package de.tutorials.user.service.internal;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import de.tutorials.user.User;
import de.tutorials.user.persistence.IUserDao;
import de.tutorials.user.service.IUserService;

@Service
public class UserService implements IUserService{
    @Autowired
    IUserDao userDao;
    
    @Override  //Diese Annotation soll weg
    public List<User> findAllUsers() {
        return userDao.findAllUsers();
    }

    @Override //Diese Annotation soll weg
    @Transactional
    public void register(User user) {
        userDao.save(user);
    }
}
Code:
package de.tutorials.user.persistence.internal;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;

import de.tutorials.user.User;
import de.tutorials.user.persistence.IUserDao;

@Repository
public class UserDao implements IUserDao {

    @PersistenceContext
    private EntityManager em;

        @Override //Diese Annotation soll weg
    @SuppressWarnings("unchecked")
    public List<User> findAllUsers() {
        return em.createQuery("from User u").getResultList();
    }

        @Override //Diese Annotation soll weg
    public void save(User user) {
        em.persist(user);
    }

}


Nachdem die geändert wurden. Maven Install
Code:
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running de.tutorials.user.service.internal.UserServiceTest
log4j:WARN No appenders could be found for logger (org.springframework.test.context.junit4.SpringJUnit4ClassRunner).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into User (name) values (?)
Hibernate: select user0_.id as id1_, user0_.name as name1_ from User user0_
Hibernate: insert into User (name) values (?)
Hibernate: select user0_.id as id1_, user0_.name as name1_ from User user0_
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.203 sec

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

Ist alles Schick. Jetzt mein Problem:
Wenn ich folgende Main Methode Starte erscheint folgende Fehler Meldung...
Code:
package de.tutorials;

import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import de.tutorials.user.Role;
import de.tutorials.user.User;
import de.tutorials.user.service.IUserService;



public class Main {
            
    public final static String applicationContextConfigurationPath = "context.xml";
    
    
    
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(applicationContextConfigurationPath);
        IUserService userService = (IUserService)context.getBean("userService");
       
        User user = new User();
        
        Role roleAdmin = new Role("admin");
        Role roleUser = new Role("user");
        
        user.getRoles().add(roleAdmin);
        user.getRoles().add(roleUser);
        user.setName("bubu");
        
        userService.register(user);
        List<User> allUsers = userService.findAllUsers();
        User savedUser = allUsers.get(0);
        System.out.println(savedUser.toString());
    }

}

Fehler:
Code:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into User (name) values (?)
Hibernate: insert into User_Role (User_id, roles_id) values (?, ?)
Exception in thread "main" org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: de.tutorials.user.Role; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: de.tutorials.user.Role
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:654)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:98)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:471)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:412)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at com.sun.proxy.$Proxy18.register(Unknown Source)
    at de.tutorials.Main.main(Main.java:33)
Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: de.tutorials.user.Role
    at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:242)
    at org.hibernate.type.EntityType.getIdentifier(EntityType.java:430)
    at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:101)
    at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:777)
    at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1165)
    at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:58)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:171)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
    at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467)
    ... 8 more
Bei Änderung
Code:
package de.tutorials.user;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import lombok.Data;

@Data
@Entity
public class User {
    @Id
    @GeneratedValue
    protected Long id;
    protected String name;

    @OneToMany(cascade = {CascadeType.ALL})
    protected Set<Role> roles = new HashSet<Role>();
}

Habe ich folgende Fehlermeldung
Code:
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into User (name) values (?)
Hibernate: insert into Role (name) values (?)
Hibernate: insert into Role (name) values (?)
Hibernate: insert into User_Role (User_id, roles_id) values (?, ?)
Hibernate: insert into User_Role (User_id, roles_id) values (?, ?)
Hibernate: select user0_.id as id1_, user0_.name as name1_ from User user0_
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: de.tutorials.user.User.roles, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
    at org.hibernate.collection.PersistentSet.toString(PersistentSet.java:332)
    at java.lang.String.valueOf(String.java:2854)
    at java.lang.StringBuilder.append(StringBuilder.java:128)
    at de.tutorials.user.User.toString(User.java:14)
    at de.tutorials.Main.main(Main.java:36)
 
Hallo,

du kannst bei dem roles Property den Fetch-type auf FeatchType.EAGER stellen, dann sollte keine LazyLoading exception mehr kommen, da dadurch beim laden eines Users auch gleich die Roles mitgeladen werden.

Ansonsten ist das Beispiel schon ziemlich alt, die neuere Version des Beispiels findest du hier:
http://www.tutorials.de/java/385530...bernate-4-x-lombok-junit-4-und-maven-3-a.html

//Edit: ich habe dir mal eine aktualisierte Fassung von dem Beispiel angehängt.
Ich verwende nun zusätzlich Java Config und Spring Data JPA.

Gruß Thomas
 

Anhänge

Zurück