我正在使用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&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这个问题的帖子,但对我来说没什么用的:(
答案 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将导致它们被预取,避免错误并为其他每个查询延迟取得它们。