2009-02-08 3 views
19

내 시스템에는 ShoppingCart와 ShoppingCartItem의 두 엔티티가 있습니다. 상당히 일반적인 유스 케이스. 그러나 쇼핑 카트를 저장하면 항목이 DB에 저장되지 않습니다.NHibernate : Fluent Nhibernate를 사용하여 자식 객체 저장

내 개체 내에서 새로운 ShoppingCart 개체를 만듭니다.

ShoppingCart cart = CreateOrGetCart(); 

그런 다음 데이터베이스에서 가져온 기존 제품을 처음에 추가하십시오.

cart.AddItem(product); 

이것은 IList에 항목을 추가하기위한 단순한 래퍼입니다.

public virtual void AddItem(Product product) 
    { 
     Items.Add(new ShoppingCartItem { Quantity = 1, Product = product }); 
    } 

I는 다음과 같습니다 저장소

Repository.SaveOrUpdate(cart); 

에 될 saveOrUpdate를 호출

public T SaveOrUpdate(T entity) 
    { 
     Session.SaveOrUpdate(entity); 
     return entity; 
    } 

나는 매핑 유창함 자 NHibernate를 사용하고 있습니다 :

public ShoppingCartItemMap() 
    { 
     WithTable("ShoppingCartItems"); 

     Id(x => x.ID, "ShoppingCartItemId"); 
     Map(x => x.Quantity); 

     References(x => x.Cart, "ShoppingCartId").Cascade.SaveUpdate(); 
     References(x => x.Product, "ProductId"); 
    } 


    public ShoppingCartMap() 
    { 
     WithTable("ShoppingCarts"); 

     Id(x => x.ID, "ShoppingCartId"); 
     Map(x => x.Created); 
     Map(x => x.Username); 

     HasMany<ShoppingCartItem>(x => x.Items) 
      .IsInverse().Cascade.SaveUpdate() 
      .WithKeyColumn("ShoppingCartId") 
      .AsBag(); 
    } 

데이터베이스 스키마 (SQL Server 2005) 상당히 일반적인 또한 :

내 shoppingCart가가 될 saveOrUpdate
CREATE TABLE [dbo].[ShoppingCarts] 
(
[ShoppingCartID] [int] NOT NULL IDENTITY(1, 1), 
[Username] [nvarchar] (50) NOT NULL, 
[Created] [datetime] NOT NULL 
) 
GO 
ALTER TABLE [dbo].[ShoppingCarts] ADD CONSTRAINT [PK_ShoppingCarts] PRIMARY KEY CLUSTERED ([ShoppingCartID]) 
GO 



CREATE TABLE [dbo].[ShoppingCartItems] 
(
[ShoppingCartItemId] [int] NOT NULL IDENTITY(1, 1), 
[ShoppingCartId] [int] NOT NULL, 
[ProductId] [int] NOT NULL, 
[Quantity] [int] NOT NULL 
) 
GO 
ALTER TABLE [dbo].[ShoppingCartItems] ADD CONSTRAINT [PK_ShoppingCartItems] PRIMARY KEY CLUSTERED ([ShoppingCartItemId]) 
GO 
ALTER TABLE [dbo].[ShoppingCartItems] ADD CONSTRAINT [FK_ShoppingCartItems_Products] FOREIGN KEY ([ProductId]) REFERENCES [dbo].[Products] ([ProductId]) 
GO 
ALTER TABLE [dbo].[ShoppingCartItems] ADD CONSTRAINT [FK_ShoppingCartItems_ShoppingCarts] FOREIGN KEY ([ShoppingCartId]) REFERENCES [dbo].[ShoppingCarts] ([ShoppingCartID]) 
GO 

, 왜 어떤 ShoppingCartItems는 저장되지 않는?

도와주세요.

감사

UPDATE : 트랜잭션에 포장 좀 더 많은 정보를 원하시면 저를 providng :

, 테이블 을 열에 'ShoppingCartId'NULL 값을 삽입 할 수 없습니다 'WroxPizza .dbo.ShoppingCartItems '; 열이 널을 허용하지 않습니다. INSERT가 실패합니다. 그 진술서는 만료되었습니다.

이것은 새로운 카트입니다.

+0

James Gregorys 솔루션이 나를 위해 일했습니다. –

답변

1

트랜잭션에서 Session.SaveOrUpdate를 래핑하거나 직접 플러시를 수행하십시오.

0

확실치 않지만 NHibernate가 자식 개체에 개체를 저장하는 것을 계단식으로 처리하지 않는다고 생각합니다. SaveOrUpdate를 호출하는 코드를 표시하지 않지만, 그 시점에서 ShoppingCartItems를 반복하면 각각을 개별적으로 저장하면 해당 코드가 유지됩니다.

0

아무 것도 없음에 대해 NHibernate (내가 사용하는 OPF는 나에게이 작업을 수행합니다.)하지만 집계 루트 (ShoppingCart)를 저장할 때 해당 합성 소유 인스턴스를 세션도?

0

장바구니 품목을 먼저 저장 한 다음 장바구니를 저장하는 것이 가능합니까? 따라서 하위 항목에는 사용할 상위 ID가 없습니다.

당신은 명시 적으로 카트를 생성시 DB에 저장 한 다음 항목을 추가하고 저장하면됩니다. 단지 ID를 얻기 위해서입니다.

2

왜 라인

References(x => x.Cart, "ShoppingCartId").Cascade.SaveUpdate() 

에서 .Cascade.SaveUpdate()을 포함 했는가?

아마도 NHibernate (또는 Fluent NHibernate)가 관계의 양쪽 끝에서 계단식 저장/업데이트가있는 것으로 혼란 스럽겠습니까?

캐스케이드하도록 HasMany를 구성하면 원하는 것을 달성하기에 충분해야합니다.

-4

sessionfactory의 구성 진술 문에 문제가 있습니다. 데이터를 보존하려면 Exposeconfiguration을 사용하지 마십시오. 그러면 데이터 지속성 문제를 반드시 해결할 수 있습니다.

+0

schemaexport의 사용은 신중하게 수행되어야합니다. –

0

데이터베이스 스키마에서 Identity를 사용하여 필드를 정의 했으므로이 필드를 Map 파일에 설정해야합니다. 다음과 같은 예 :

Id(x => x.ID, "ShoppingCartItemId").GeneratedBy.Identity();

당신은 매핑의 ID 필드를 설정하지 않았기 때문에 당신이 점점 오류가 신원에 의해 생성되는, 따라서 당신이) (저장하려고은 Identity 열이 생성되지 않고 (데이터베이스에서 널이 아닌 것으로 설정된 경우) 오류가 발생합니다.

관련 문제