【问题标题】:JsonMappingException - Cannot map valid objectJsonMappingException - 无法映射有效对象
【发布时间】:2014-09-22 10:31:59
【问题描述】:

我需要在@Test 方法中使用jackson.map.ObjectMapper 映射新创建的对象:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
@WebAppConfiguration
public class TestProductServiceController implements ApplicationContextAware  {
    @Autowired
    private ProductService cService;
    @Autowired
    private ProductPropertyService crService;
    @Autowired
    private SessionFactory sessionFactory;

    String json;
    ProductProperty productProperty;
    Product product;
    ObjectMapper mapper = new ObjectMapper();

    @Before
    public void setUp() throws IOException {
        RestAssuredMockMvc.standaloneSetup(new ProductServiceController());
        cService = (ProductService) context.getBean("productService");
    }

    @Test
    public void testAddProduct() throws IOException {
        productProperty = crService.findProductProperty(1);
        product = new Product();
        product.setProduct(1); 
        product.setDateTimeStart(...);
        product.setDateTimeEnd(...);
        product.setFk_product_property(productProperty);
        product.setName("Test 1");
        product.setCancelled("F");
        Hibernate.initialize(product);
        Hibernate.initialize(product.getMapped_product_part_collection());
        Hibernate.initialize(productProperty);
        Hibernate.initialize(productProperty.getMapped_fk_product_property());
        String jsonStr = mapper.writeValueAsString(product);
        }
private static ApplicationContext context;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    context = applicationContext;
}

public static ApplicationContext getContext() {
    return context;
}
     }

错误:

 JsonMappingException  failed to lazily initialize a collection of role: model.ProductProperty.mapped_fk_product_property,
         could not initialize proxy - no Session
         (through reference chain: model.Product["fk_product_property"]->model.ProductProperty["mapped_fk_product_property"])

@Table(name = "product")
@Entity
public class Product implements Serializable {
  @Id
  @Column(name = "product")
  private int product;

@ManyToOne
  @JoinColumn(name = "fk_product_property", referencedColumnName = "product_property", nullable = false)
  private ProductProperty fk_product_property;
  }

@Entity
@Table(name = "product_property")
public class ProductProperty implements Serializable {

  @Id
  @GeneratedValue
  @Column(name = "product_property")
  private int product_property;
  @OneToMany(mappedBy = "fk_product_property", cascade={CascadeType.ALL})
      private Collection<Product> mapped_fk_product_property;
      }

我认为将fetch = FetchType.EAGER 应用于@OneToMany(mappedBy = "fk_product_property", cascade={CascadeType.ALL}) private Collection<Product> mapped_fk_product_property; 是不正确的。怎么了?当前@TEST方法的解决方案是什么?

更新

我添加到@TEST 但出现错误:

Hibernate.initialize(product);
Hibernate.initialize(product.getMapped_product_part_collection());
Hibernate.initialize(productProperty.getMapped_fk_product_property()); //    HibernateException: collection is not associated with any session

更新 2

我在Hibernate.initialize(productProperty.getMapped_fk_product_property()); 的调试器中有以下结构:

-product={...}
  -name=...
  -....
  -fk_product_property = {....}
     -name=...
     -....
     -mapped_fk_product_property={org.hibernate.collection.internal.PersistentBag@2222} unable to evaluate expression Method threw 'org.hibernate.LazyInitializationException' exception.

【问题讨论】:

  • 不需要fetch = FetchType.EAGER,而是在String jsonStr = mapper.writeValueAsString(product);之前尝试使用Hibernate.intialize(product);Hibernate.intialize(product.getmapped_fk_product_property());
  • 如果它解决了您的问题,请告诉我
  • 它给了org.hibernate.HibernateException: collection is not associated with any session
  • productProperty.getMapped_fk_product_property() 无法初始化,因为它位于 DAO,而不是服务中。
  • 无论它位于何处,在包装成 json 之前先尝试初始化它

标签: java spring hibernate jackson


【解决方案1】:

ProductPropertyProduct 之间的关系是 OneToMany 并且关联的所有者是 Product,因此当您尝试获取 ProductProperty 元素时,如果获取,Product 将不会被加载策略不是EAGER

现在在这行代码中:

productProperty = crService.findProductProperty(1);

您正试图从您的服务类crService 中获取ProductProperty 元素。这意味着获取逻辑存在于您拥有 Hibernate 的Session 的 DAO 层中 此外集合元素mapped_fk_product_property 将被设置为代理对象,因为在这种情况下获取策略是LAZY

现在在这行代码中:

Hibernate.initialize(productProperty.getMapped_fk_product_property());

您正在尝试使用Hibernate.initialize(Object) 初始化集合元素,这行代码的问题是您尝试在DAO 层本身关闭会话后调用初始化。所以异常说:

could not initialize proxy - no Session

要解决此问题,请在您尝试获取 ProductProperty 的 DAO 层中添加这行代码:

Hibernate.initialize(productProperty.getMapped_fk_product_property());

此外,根据 Java 编码指南,不建议在变量声明中使用下划线“_”,因此请尽量避免在代码中使用它们。

【讨论】:

  • 我找到了解决方法:在ProductPropertyDAO 我设置setMapped_fk_product_property(null) 据我所知,没有其他方法可以获取。我认为没有理由获取这些,因为已经存在关系并且这只是一个孩子(父母是Product)。这是正确的吗?如果没有提供代码示例,因为Hibernate.initialize(....) 似乎没有帮助。
  • @RCola,用清晰的解释更新了我的答案。你在错误的地方调用初始化,它应该只在你打开会话的地方调用,而不是在会话关闭后调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-31
  • 2022-01-10
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 2017-01-19
相关资源
最近更新 更多