【问题标题】:JPA no session when calling child呼叫孩子时JPA没有会话
【发布时间】:2014-03-29 13:21:13
【问题描述】:

我正在使用 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;
    }

这里是用户存储库:

    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;
    }

}

和用户存储库:

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);
}

还有我为 Spring Security 提供的服务:

@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 问题的帖子,但对我没有任何作用:(

【问题讨论】:

    标签: spring jpa spring-data-jpa


    【解决方案1】:

    使用获取所需数据的查询,以便在需要时出现。

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

    当您想要访问权限时使用 findByUsernameFetchAuthorities 会导致它们被预取,从而避免错误并保持它们在其他查询时延迟获取。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-23
      相关资源
      最近更新 更多