2016-06-07 102 views
0

由于无限递归,我有StackOverflowError的问题。 我CONFIGS:Spring数据,JPA,休眠 - 双向关系无限递归

applicatinContext.xml(部分)

<bean id="entityManagerFactory" 
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" lazy-init="true" 
    p:persistenceProviderClass="org.hibernate.jpa.HibernatePersistenceProvider" 
    p:persistenceXmlLocation="classpath:persistence.xml" 
    p:persistenceUnitName="hibernate-persistent" 
    p:packagesToScan="pl.roszkow.webpage.entities"/> 

<bean id="transactionManager" 
     class="org.springframework.orm.jpa.JpaTransactionManager" 
    p:entityManagerFactory-ref="entityManagerFactory"/> 

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/> 
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/> 
<jpa:repositories base-package="pl.roszkow.webpage.repositories"/> 
<tx:annotation-driven transaction-manager="transactionManager"/> 

persistance.xml

<persistence-unit name="hibernate-persistent" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> 
    <properties> 
     <property name="hibernate.ejb.cfgfile" value="classpath:hibernate.cfg.xml"/> 
    </properties> 
</persistence-unit> 

的hibernate.cfg.xml

<hibernate-configuration> 
<session-factory> 
    <property name="hibernate.connection.driver_class">org.sqlite.JDBC</property> 
    <property name="hibernate.connection.url">jdbc:sqlite::resource:roszkow.db</property> 
    <property name="hibernate.connection.username"/> 
    <property name="hibernate.connection.password"/> 

    <!-- SQL --> 
    <property name="hibernate.dialect">pl.roszkow.webpage.utils.SQLiteDialect</property> 
    <property name="hibernate.hbm2ddl.auto">update</property> 
    <property name="hibernate.show_sql">true</property> 
    <property name="hibernate.format_sql">true</property> 

    <!-- C3P0 --> 
    <property name="hibernate.c3p0.acquire_increment">2</property> 
    <property name="hibernate.c3p0.max_size">10</property> 
    <property name="hibernate.c3p0.min_size">5</property> 
    <property name="hibernate.c3p0.timeout">180</property> 
    <property name="hibernate.c3p0.idle_test_period">100</property> 
</session-factory> 
</hibernate-configuration> 

的web.xml

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
     classpath:/applicationContext.xml 
     classpath:/securityContext.xml 
    </param-value> 
</context-param> 

<servlet> 
    <servlet-name>dispatcher</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>classpath:/securityContext.xml</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
<servlet-mapping> 
    <servlet-name>dispatcher</servlet-name> 
    <url-pattern>/</url-pattern> 
</servlet-mapping> 

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<filter> 
    <filter-name>SpringOpenEntityManagerInViewFilter</filter-name> 
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> 
    <init-param> 
     <param-name>entityManagerFactoryBeanName</param-name> 
     <param-value>entityManagerFactory</param-value> 
    </init-param> 
    <init-param> 
     <param-name>flushMode</param-name> 
     <param-value>AUTO</param-value> 
    </init-param> 
</filter> 
<filter-mapping> 
    <filter-name>SpringOpenEntityManagerInViewFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

而现在我的实体,User.java

@Entity 
@Table(name = "users") 
public class User implements UserDetails, Serializable { 
    private static final long serialVersionUID = -3170642319755386686L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    @Column(nullable = false, unique = true) 
    private String email; 

    @Column(nullable = false) 
    private String password; 

    @Column(name = "first_name", nullable = false) 
    private String firstName; 

    @Column(name = "last_name", nullable = false) 
    private String lastName; 

    @Column(name = "birth_date", nullable = false) 
    private Timestamp birthDate; 

    private Boolean enabled = false; 

    private String role = "ROLE_USER"; 

    @OneToMany(mappedBy = "author") 
    private List<Article> articles; 

    @Override 
    public Collection<? extends GrantedAuthority> getAuthorities() { 
     List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 
     authorities.add(new SimpleGrantedAuthority(this.role)); 
     return authorities; 
    } 

    @Override 
    public String getUsername() { 
     return this.email; 
    } 

    @Override 
    public boolean isAccountNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isAccountNonLocked() { 
     return true; 
    } 

    @Override 
    public boolean isCredentialsNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isEnabled() { 
     return this.enabled; 
    } 
} 

和Article.java

@Entity 
@Table(name = "articles") 
public class Article implements Serializable { 
    private static final long serialVersionUID = -6523854154438579850L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    @NotBlank(message = "{article.title.notBlank}") 
    @Column(nullable = false) 
    private String title; 

    @NotBlank(message = "{article.content.notBlank}") 
    @Column(nullable = false) 
    private String content; 

    @Column(name = "add_date", nullable = false) 
    private Timestamp addDate; 

    @ManyToOne 
    @JoinColumn(name = "author_id", nullable = false) 
    private User author; 

    /*@OneToMany(mappedBy = "article") 
    private List<Image> images;*/ 
} 

库,UsersRepo.java

@Repository 
public interface UsersRepository extends CrudRepository<User, Long> { 

List<User> findAll(); 

User findOne(Long id); 

User findByEmail(String email); 

User save(User user); 
} 

ArticlesRepo.java

@Repository 
public interface ArticlesRepository extends CrudRepository<Article, Long> { 

@Query("select a from Article a order by a.addDate desc") 
List<Article> findAll(); 

Article findOne(Long id); 

Article save(Article article); 

void delete(Long id); 
} 

当应用程序尝试加载用户实体中的文章集合时发生错误。但延迟加载集合shuldn​​'t完全加载。从课堂上删除集合时,一切正常。

有人能说我的应用有什么问题吗?我想延迟加载不能正常工作。

早些时候,我也遇到了LazyInitializationException的问题,但通过将SpringOpenEntityManagerInViewFilter添加到web.xml来解决此问题。

堆栈跟踪

java.lang.StackOverflowError 
java.lang.Long.stringSize(Long.java:306) 
java.lang.Long.toString(Long.java:242) 
java.lang.Long.toString(Long.java:100) 
java.lang.String.valueOf(String.java:2945) 
java.lang.Long.toString(Long.java:740) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
pl.roszkow.webpage.entities.Article.toString(Article.java:30) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
java.util.AbstractCollection.toString(AbstractCollection.java:422) 
org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:510) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
pl.roszkow.webpage.entities.User.toString(User.java:35) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
pl.roszkow.webpage.entities.Article.toString(Article.java:30) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
java.util.AbstractCollection.toString(AbstractCollection.java:422) 
org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:510) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
pl.roszkow.webpage.entities.User.toString(User.java:35) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
pl.roszkow.webpage.entities.Article.toString(Article.java:30) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
java.util.AbstractCollection.toString(AbstractCollection.java:422) 
org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:510) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
pl.roszkow.webpage.entities.User.toString(User.java:35) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
pl.roszkow.webpage.entities.Article.toString(Article.java:30) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
java.util.AbstractCollection.toString(AbstractCollection.java:422) 
org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:510) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
pl.roszkow.webpage.entities.User.toString(User.java:35) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
pl.roszkow.webpage.entities.Article.toString(Article.java:30) 
java.lang.String.valueOf(String.java:2826) 
java.lang.StringBuilder.append(StringBuilder.java:115) 
java.util.AbstractCollection.toString(AbstractCollection.java:422) 
org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:510) 
java.lang.String.valueOf(String.java:2826) 
+0

哪里是你的形象类。你可以添加它的代码 –

+0

请张贴您的错误堆栈跟踪.... – kamokaze

+0

添加stacktrace。 @TanviB我评论了图片集,错误持续存在。 – zach

回答

0

试试这个:添加@JsonBackReference

@JsonBackReference 
@ManyToOne(fetch=FetchType.LAZY) 
@JoinColumn(name = "author_id", nullable = false) 
private User author; 

编辑:

尝试与

@JsonManagedReference 
    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name = "author_id", nullable = false) 
    private User author; 
+0

添加了注释,但没有任何更改,错误持续 – zach

0

试试这个:

@Entity 
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") 
@Table(name = "users") 
public class User implements UserDetails, Serializable { 
    private static final long serialVersionUID = -6523854154438579850L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 
.... 

@Entity 
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") 
@Table(name = "articles") 
public class Article implements Serializable { 
    private static final long serialVersionUID = -6523854154438579850L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 
.... 
+0

JsonIdentityInfo注释也没有工作 – zach