-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 
Author Message
 Post subject: @Id and its unsaved-value
PostPosted: Tue Feb 14, 2006 5:34 pm 
Beginner
Beginner

Joined: Fri Aug 27, 2004 1:59 pm
Posts: 33
I am having problems with @Id and its unsaved-value. I would like the unsaved-value to default to something without an instance being created. But the code in UnsavedValueFactory.getUnsavedIdentifierValue seems to choose to try to instantiate an instance before it checks whether the @Id is of a primitive type:

Code:
      if ( unsavedValue == null ) {
         if ( identifierGetter!=null && constructor!=null ) {
            // use the id value of a newly instantiated instance as the unsaved-value
            Serializable defaultValue = (Serializable) identifierGetter.get( instantiate(constructor) );
            return new IdentifierValue( defaultValue );
         }
         else if ( identifierGetter != null && (identifierType instanceof PrimitiveType) ) {
            Serializable defaultValue = ( ( PrimitiveType ) identifierType ).getDefaultValue();
            return new IdentifierValue( defaultValue );
         }
        ...


I don't really need the default constructor. If I get rid of it, I get past determining the unsaved-value, but then fail later on in PojoInstantiator.instantiate.

Is there some other trick? Or should the if conditions in UnsavedValueFactory.getUnsavedIdentifierValue be swapped?

-barry

Hibernate version: 3.1.2

Mapping documents:

Code:
package org.opentrader.platform.samples.springconfigurable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.springframework.beans.factory.annotation.Configurable;

@Entity @Table(name = "orders")
@Configurable("Order")
public class Order {
   
    public Order() {}
   
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    @SuppressWarnings("unused")
    private long oid;
   
    @Column(updatable=false)
    private String orderId;
   
    private int state = StateStrategy.PENDING;
   
    @Transient
    private StateStrategy stateStrategy;   
   
    public void setStateStrategy(StateStrategy stateStrategy) {
        this.stateStrategy = stateStrategy;
    }
   
    public StateStrategy getStateStrategy() {
        return stateStrategy;
    }
   
    //---- ---- ----
   
    public Order(String orderId) {
        this.orderId = orderId;
    }
   
    public long getOID() {
        return oid;
    }
   
    public String getOrderId() {
        return orderId;
    }
   
    public void onEvent() {
        this.state = stateStrategy.transition(state);
    }
   
    public int getState() {
        return state;
    }
   
}


Code between sessionFactory.openSession() and session.close():

N/A

Full stack trace of any exception that occurs:

Sigh, testng will not let me copy the stack trace.....

Name and version of the database you are using:

N/A

The generated SQL (show_sql=true):

N/A

Debug level Hibernate log excerpt:


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 16, 2006 10:09 am 
Beginner
Beginner

Joined: Fri Aug 27, 2004 1:59 pm
Posts: 33
FYI: http://opensource2.atlassian.com/projec ... e/HHH-1495


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 16, 2006 11:39 am 
Beginner
Beginner

Joined: Fri Aug 27, 2004 1:59 pm
Posts: 33
From Christian Bauer in the jira issue:

Quote:
Use Interceptor.isTransient(), stay on the forum. This is not a support system.


Can anyone shed some light as to what this might mean? The problem I am seeing is deep in the hibernate internals as the annotations are being parsed. How could the use Interceptor.isTransient() help to resolve the issue I described. Am I missing something?

thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 17, 2006 5:38 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
You will need to explain the problem more precisly. e.g. what is the stacktrace ?

What happens if you don't include the default constructor and why is it not ok for hibernate to create the object to find out what the default unsaved value is ?

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 17, 2006 9:10 am 
Beginner
Beginner

Joined: Fri Aug 27, 2004 1:59 pm
Posts: 33
Thanks Max,

My reason for not wanting an instance created to determine the unsaved-value is (ah, the hibernate team will not like this I think) because I am using spring to configure persistent beans via the @Configure annotation. This annotation triggers an aspectj aspect to initialize the instance in the same way as if spring had created the bean. But since the SessionFactory is created during the bootstrap process, the spring contexts are not yet ready and I hit a race condition.

The above aside, and after pondering unsaved-values further, unless there is to be an explicit @UnsavedValue annotation hibernate really /must/ create an instance to determine the unsaved value. Because if the class does initialize the property during construction, reversing the if-conditions in UnsavedValueFactory.getUnsavedIdentifierValue would prevent the class specified default value from ever being considered. (ie, it would simply use 0 in the case of an long, even though the class may specify "@Id private long id = 1010").

So really what I want is for spring to not attempt to configure a bean when created by UnsavedValueFactory. And this is easy enough using my own aspect:

Code:
@Aspect
public class HibernateAwareAnnotationBeanConfigurerAspect extends BeanConfigurerSupport {

    public HibernateAwareAnnotationBeanConfigurerAspect() {
        setBeanWiringInfoResolver(new AnnotationBeanWiringInfoResolver());
    }

    @Pointcut("initialization((@org.springframework.beans.factory.annotation.Configurable *).new(..)) && this(beanInstance)")
    void beanCreation(Object beanInstance) {}
   
    @Pointcut("call(* org.hibernate.engine.UnsavedValueFactory.instantiate(..)) && within(org.hibernate.engine.UnsavedValueFactory)")
    void hibernateUnsavedValueFactory() {}
   
    @AfterReturning("beanCreation(beanInstance) && !cflow(hibernateUnsavedValueFactory())")
    public void configure(Object beanInstance) {
        configureBean(beanInstance);
    }
}


Well, aside from an aspectj bug that prevents this aspect weaving correctly. Once I get thru the aspectj issues, I will post this to the hibernate wiki, as others spring users have been troubled with this exact race condition.

-barry


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 17, 2006 10:22 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
so your POJO's has a hard dependency on dao's or ? doesnt sound good.

anyway, i would say in your case the right thing is to push for having support for unsaved-value in annotations (i don't think it is there yet)

because the problem is not about there being a default constructor the problem is that you do not want these objects constructucted "too early" and for that your suggested workaround seems fair.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 17, 2006 7:38 pm 
Beginner
Beginner

Joined: Fri Aug 27, 2004 1:59 pm
Posts: 33
max wrote:
so your POJO's has a hard dependency on dao's or ? doesnt sound good.


Why do you say that? My pojo has no hard dependencies on anything, it doesn't even use a dao. They are simply pojos with whatver dependencies are appropriate for the application, and where the concrete dependent instances are injected in by spring.

I agree that unsaved-value in annotations would be best.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 20, 2006 5:00 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
sorry, wrong wording...

from what i understand they have a hard (runtime) dependency on injection being performed....

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject: Re: @Id and its unsaved-value
PostPosted: Tue Feb 10, 2015 2:11 pm 
Newbie

Joined: Tue Feb 10, 2015 2:08 pm
Posts: 1
I note on https://hibernate.atlassian.net/browse/HHH-1495?jql=text%20~%20%22Instance%20should%20not%20be%20created%20to%20determine%20unsaved-value%22 that another duplicate issue was going to be filed for this.

Did that ever happen?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.