openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Craig L Russell <Craig.Russ...@Sun.COM>
Subject Re: NPE on ManyToOne while using insertable = false, updatable = false
Date Thu, 03 Jan 2008 04:03:44 GMT
Hi Gilberto,

I think you might have encountered an issue with caching.

When you persist the Item entity, the reference to Produto is null (I  
didn't see anywhere that you set it). So when you retrieve it,  
openjpa doesn't go to the database but simply returns what is in the  
(second level) cache. In the cache, the object that was stored is  
retrieved.

JPA spec (at the JPA 1.0 level) that the application manage both  
sides of relationships. In the code below, can you add a statement  
that sets the Produto field in Item before commit?

On Jan 2, 2008, at 9:33 AM, Gilberto C Andrade wrote:

> Hi,
>
> openjpa 1.0.1, jdk 1.5
> Produto:
>> @Entity
>> @Table(name = "produto")
>> public class Produto implements Serializable {
>>     @Id
>>     @GeneratedValue(strategy=GenerationType.TABLE,  
>> generator="ProdutoGerador")
>>     @TableGenerator(name="ProdutoGerador", table="ID_GERADOR",  
>> pkColumnName="PK",
>>         valueColumnName="AID", pkColumnValue="produto_id_gerador",  
>> allocationSize=1, initialValue=1)
>>     @Column(name="cd_produto", columnDefinition="INTEGER")
>>     private Integer cdProduto;
>
> Item:
>> @Entity
>> @Table(name = "item")
>> public class Item implements Serializable {
>>     @Transient
>>     protected final Log log = LogFactory.getLog(getClass());
>>     @Id
>>     @GeneratedValue(strategy=GenerationType.TABLE,  
>> generator="ItemGerador")
>>     @TableGenerator(name="ItemGerador", table="ID_GERADOR",  
>> pkColumnName="PK",
>>         valueColumnName="AID", pkColumnValue="item_id_gerador",  
>> allocationSize=1, initialValue=1)
>>     @Column(name="cd_item", columnDefinition="INTEGER")
>>     private Integer cdItem;
> .
> .
> .
>>
>>     @Column(name = "cd_produto")
>>     private Integer cdProduto;
>>
>>     @ManyToOne
>>     @JoinColumn(name = "cd_produto",  
>> referencedColumnName="cd_produto", insertable = false, updatable =  
>> false)
>>     private Produto produto;//read only
>
> OBS.: Originally this was mapped the following way, using  
> hibernate's tag:
>>       <many-to-one
>>             name="produto"
>>             class="org.appfuse.model.estoque.Produto"
>>             cascade="none"
>>             outer-join="true"
>>             update="false"
>>             insert="false"
>>             access="property"
>>             column="cd_produto"
>>         />
>
>
>
> Test:
>>     @Test
>>     public void persistRemoveItemTest() {
>>         log.debug("\npersistRemoveItemTest - Criação de uma  
>> instância da classe Item\n");
>>         String nomeItem = "Calça";
>>         Integer cdItem = null;
>>         BigDecimal precoVenda = new BigDecimal(0.0F);
>>         BigDecimal precoCusto = new BigDecimal(0.0F);
>>         UnidadeMedida uM = em.find(UnidadeMedida.class, "MT");
>>         Float estoqueAtual = 0.0F;
>>         Float estoqueMinimo = 0.0F;
>>         Float nivelDeReposicao = 0.0F;
>>         Boolean flDescontinuado = false;
>>         Produto p = em.find(Produto.class, 1);
>>
>>         Item i = new Item(nomeItem,precoVenda, precoCusto,  
>> uM.getCdUnidadeMedida(), estoqueAtual, estoqueMinimo,  
>> nivelDeReposicao, flDescontinuado, p.getCdProduto());

i.setProduto(p); // <== here's the solution

Craig

>>         assertNull("cdItem antes do método persist:",i.getCdItem());
>>         em.getTransaction().begin();
>>         em.persist(i);
>>         em.getTransaction().commit();
>>         log.debug("Objeto pós gravação: \n"+i);
>>         cdItem = i.getCdItem();
>>         i = null;
>>
>>         assertNotNull("cdItem pós persist:",cdItem);
>>
>>         Item i2 = em.find(Item.class, cdItem);
>>         log.debug("Objeto carregado: \n"+i2);
>>         assertNotNull("Não pode ser nulo:",i2.getProduto 
>> ());<==================== Here is the problem!
>>     }
>
> As you can see I'm testing the lazy load of the Produto class. But i2
> instance comes with null produto.
>
> Is there anything wrong with my mapping?
>
> Thanks,
>
> Gilberto

Craig Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!


Mime
View raw message