JPA在打电话给孩子时没有会话

时间:2014-02-26 15:35:05

标签: spring jpa spring-data-jpa

我正在使用spring-data-jpa和JPA存储库

这是我的源代码

<beans:bean id="producerService" class="cz.services.RepositoryProducerService" />
<jpa:repositories base-package="cz.repository" />

<beans:bean id="myEmf"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <beans:property name="dataSource" ref="dataSource" />
    <beans:property name="packagesToScan" value="cz.models" />
    <beans:property name="jpaVendorAdapter">
        <beans:bean
            class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </beans:property>
    <beans:property name="jpaProperties">
        <beans:props>

            <beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
            </beans:prop>
            <beans:prop key="hibernate.show_sql">true</beans:prop>
        </beans:props>
    </beans:property>
</beans:bean>

<beans:bean id="transactionManager"
    class="org.springframework.orm.jpa.JpaTransactionManager">
    <beans:property name="entityManagerFactory" ref="myEmf" />
</beans:bean>

<beans:bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <beans:property name="url"
        value="jdbc:mysql://localhost:3306/mydb?zeroDateTimeBehavior=convertToNull&amp;characterEncoding=UTF-8" />

    <beans:property name="username" value="root" />
    <!--<property name="password" value="test" /> -->
    <beans:property name="password" value="test"></beans:property>
</beans:bean>

这是我的实体和存储库类:

package cz.models;

import java.io.Serializable;
import javax.persistence.*;
import java.util.List;


/**
 * The persistent class for the users database table.
 * 
 */
@Entity
@Table(name="users")
@NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    private int enabled;

    private String password;

    private String username;

    //bi-directional many-to-one association to Authority
    @OneToMany(mappedBy="user")
    private List<Authority> authorities;

    //bi-directional many-to-one association to Room
    @OneToMany(mappedBy="user")
    private List<Room> rooms;

    //bi-directional many-to-one association to UsersData
    @OneToMany(mappedBy="user")
    private List<UsersData> usersData;

    public User() {
    }

    ....

    public List<Room> getRooms() {
        return this.rooms;
    }

这里是User Repository:

    public void setRooms(List<Room> rooms) {
        this.rooms = rooms;
    }

    public Room addRoom(Room room) {
        getRooms().add(room);
        room.setUser(this);

        return room;
    }

    public Room removeRoom(Room room) {
        getRooms().remove(room);
        room.setUser(null);

        return room;
    }

    public List<UsersData> getUsersData() {
        return this.usersData;
    }

    public void setUsersData(List<UsersData> usersData) {
        this.usersData = usersData;
    }

    public UsersData addUsersData(UsersData usersData) {
        getUsersData().add(usersData);
        usersData.setUser(this);

        return usersData;
    }

    public UsersData removeUsersData(UsersData usersData) {
        getUsersData().remove(usersData);
        usersData.setUser(null);

        return usersData;
    }

}

和userRepository:

public interface UserRepository extends JpaRepository<User, Integer> {
    @Transactional
    @Query("select u from User u WHERE u.enabled = 1 ")
    public List<User> findAllactiveUsers();
    @Transactional
    @Query("select u from User u WHERE u.username = :username ")
    public User findByUsername(@Param("username")String username);
}

和我的春季安保服务:

@Service
public class MyUserDetailsService implements UserDetailsService {

    @Resource
    UserRepository repositoryUser;
    @Resource
    AuthorityRepository repositoryAuthority;

    public UserDetails loadUserByUsername(String username) {
        System.out.println("start");
        cz.models.User userModel = null;
        UserDetails userDetail = null;
        try{
            userModel = repositoryUser.findByUsername(username);

        // User user = userModel;
        System.out.println(userModel.getUsername());

        List<Authority> authorities = repositoryAuthority.findAllByUser(userModel);
//      repositoryUserData.findAll();
        System.out.println(userModel.getAuthorities().size());
        Collection<SimpleGrantedAuthority> collectionAuthorities = new ArrayList<SimpleGrantedAuthority>();
        for (int i = 0; i < authorities.size(); i++) {
            collectionAuthorities.add(new SimpleGrantedAuthority(authorities
                    .get(i).getAuthority()));
        }

         userDetail = new User(userModel.getUsername(),
                userModel.getUsername(), collectionAuthorities);
        }catch(Exception e){
            e.printStackTrace();
        }
        return userDetail;

    }
}

问题是:当我想要电话时 - 这个代码的和平:

userModel.getAuthorities()

调用child(db中的fk)。我有例外:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session

当我添加第二个存储库权限时,我没有这个没有会话问题。但我不想在我的存储库中创建每次方法。

List<Authority> authorities = repositoryAuthority.findAllByUser(userModel);

我必须使用hibernate.LazyInitialization而不是eanger。(和一些稳定的)

我看到很多关于JPA这个问题的帖子,但对我来说没什么用的:(

1 个答案:

答案 0 :(得分:1)

使用一个查询来获取您想要的数据,以便在需要时将其存在。

@Query("select u from User u left join fetch u.authorities WHERE u.username = :username ")
public User findByUsernameFetchAuthorities(@Param("username")String username);

当您想要访问权限时使用findByUsernameFetchAuthorities将导致它们被预取,避免错误并为其他每个查询延迟取得它们。