Tuesday 30 March 2010

Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists:

Are you working on Hibernate Many-To-One/One-To-Many with MySQL? If you're, then beware of this culprit. So how does it happens? You have two objects say 'Site' and 'Partner'. Here 'A' Partner will be dealing with multiple sites and hence the multiplicity of Many-To-One and One-To-Many mapping from both objects.

For example the Site mapping will resemble something like this;
  @Entity
  @Table(name = "site")
  public class Site
  {
    private Partner partner;
    public Site()
    {
      super();
    }

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "partnerid", nullable = true)
    public Partner getPartner()
    {
      return partner;
    }

    public void setPartner(Partner partner)
    {
      this.partner = partner;
    }
  }

While the Partner object mapping will resemble something like this;
  @Entity
  @Table(name = "partner")
  public class Partner
  {
    private List<Site> sites;
    public Partner()
    {
      super();
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "partner")
    public List<Site> getSites()
    {
      return sites;
    }

    public void setSites(List<Site> sites)
    {
      this.sites = sites;
    }
  }


From the above mappings, you'll notice that Partner has been mapped to Site using the partnerid of MySQL Table partner. A physical schema for partner and site Tables looks like this;
 Partner:
 +-----------+-------------+------+-----+
 | Field     | Type        | Null | Key |
 +-----------+-------------+------+-----+
 | id        | int(11)     | NO   | PRI |
 | name      | varchar(50) | NO   |     |
 +-----------+-------------+------+-----+

 Site:
 +-----------+-------------+------+-----+
 | Field     | Type       | Null  | Key |
 +-----------+-------------+------+-----+
 | id        | int(11)    | NO    | PRI |
 | sitename  | varchar(50)| NO    |     |
 | partnerid | int(11)    | NO    |     |
 +-----------+-------------+------+-----+
 

Because the PartnerID is integer if you have a method say getParent() in Site for example like this;
  @Transient
  public Company getParent()
  {
    if (!(getPartner() == null))
    {
      return getPartner();
    }
    return null;
  }

In MySQL , default integer is '0' , not NULL. This will cause Hibernate String to load a Partner with non-existent row with id=0 and therefore throw:
 Exception in thread "main" org.hibernate.ObjectNotFoundException: No
 row with the given identifier exists: [com.lop.testing.Partner#0]at
 org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:409)at
 org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:108)at
 org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:97)at
 org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:140)at
 org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)at
 com.essensys.bluefin.Partner_$$_javassist_10.toString(Partner_$$_javassist_10.java)at 
 java.lang.String.valueOf(String.java:2826) at java.lang.StringBuilder.append(StringBuilder.java:115)

To resolve this, simply annotate the Site getPartner() method as shown below;
  @ManyToOne(fetch = FetchType.LAZY, optional = false)
  @JoinColumn(name = "partnerid", nullable = true)
  @NotFound(action = NotFoundAction.IGNORE)
  public Partner getPartner()
  {
    return partner;
  }

The existance
@NotFound(action = NotFoundAction.IGNORE)
fix the issue.
Job done! but then the question is, do you need to go through that?

Tuesday 23 March 2010

java.lang.NoSuchMethodError: javax.xml.ws.WebFault.messageName()Ljava/lang/String

What a weird title to start with. I have to say the caption needs to be pretty straight forward to address the related issue. So what is it? Apache CXF developers working on JAX-WS OR JAX-RS project on Maven and Java 6 are likely to experience this exception.


Exception in thread "main" java.lang.NoSuchMethodError: javax.xml.ws.WebFault.messageName()Ljava/lang/String;
[java] at com.sun.xml.ws.model.RuntimeModeler.processExceptions(RuntimeModeler.java:1162)
[java] at com.sun.xml.ws.model.RuntimeModeler.processDocWrappedMethod(RuntimeModeler.java:898)
[java] at com.sun.xml.ws.model.RuntimeModeler.processMethod(RuntimeModeler.java:666)
[java] at com.sun.xml.ws.model.RuntimeModeler.processClass(RuntimeModeler.java:420)
[java] at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel

After digging around you'll realised the only option is to download the webservices-api.jar file, plus wack it onto C:\Program Files\Java\jdk1.6.0_18\jre\lib\endorsed directory to resolve it.

You might have probably ask yourself by now, where to grab webservices-api.jar easily from? two advice, download metro, unzip its content and the finally reach the lib directory to locate it OR right here.

Hold on! does it really resolves it? You are likely to enter into another annoyance when finally below exception spits onto your console log:

Exception in thread "main" java.lang.ClassCastException: $Proxy66 cannot be cast to com.sun.xml.internal.ws.developer.WSBindingProvider.

Like most people, the first thing that comes to mind is revisit and amend your service login object to see if it does the job. You are likely also to be told 'since you’re using CXF and not the JAX-WS reference implementation, the steps to set headers are probably going to be different and therefore Check the CXF docs', forgetting Apache CXF supports both JAX-WS OR JAX-RS implementations.

I tell you what don't explode yourself from annoyance, just take a close look at the Exception. You're referencing some of your object imports from com.sun.xml.internal.ws, and there is where your issue is.

Do NOT bombard yourself with new exceptions trying to regenerate your stubs with extra arguments as shown below, suggested by few people on the web.


-exsh
true


To resolve this Exception, just replace;

import com.sun.xml.internal.bind.api.JAXBRIContext;
import com.sun.xml.internal.ws.api.message.Header;
import com.sun.xml.internal.ws.api.message.Headers;
import com.sun.xml.internal.ws.developer.WSBindingProvider;

With

import com.sun.xml.bind.api.JAXBRIContext;
import com.sun.xml.ws.api.message.Header;
import com.sun.xml.ws.api.message.Headers;
import com.sun.xml.ws.developer.WSBindingProvider;


Job done! Now go grab a cuppa coffee and relax.