SourceForge.net Logo
Main Overview Wiki Issues Forum Build Fisheye
Issue Details (XML | Word | Printable)

Key: CMP-560
Type: Bug Bug
Status: Open Open
Priority: Major Major
Assignee: Shay Banon
Reporter: Piotr Zieleziński
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Compass

Error when resolving getters when overriding return types.

Created: 29/Feb/08 09:07 AM   Updated: 29/Feb/08 09:17 AM
Component/s: Compass::Core
Affects Version/s: 2.0 M1
Fix Version/s: None


 Description  « Hide
Based on:
http://forum.compass-project.org/thread.jspa?threadID=215234&tstart=0

Hi,
I have a very difficult to reproduce error. I'm using Java 6 and Compass 2.0M1 and new feature with overriding methods with more specified return type.
Some code to illustrate this:

public interface TestInterface { Serializable getId(); }

@Searchable
public class TestClass implements TestInterface {
private String id;

/* (non-Javadoc)

  • @see test.compass.method.TestInterface#getId()
    */
    @Override
    @SearchableId(accessor = "property")
    public String getId() { return id; }
    // other stuff
    }

So sometimes i get an exception:
org.compass.core.mapping.MappingException: No converter defined for type http://java.io.Serializable
at org.compass.core.config.process.MappingProcessorUtils.resolveConverterByClass(M appingProcessorUtils.java:155)
at org.compass.core.config.process.MappingProcessorUtils.lookupConverter(MappingPr ocessorUtils.java:74)
at org.compass.core.config.process.MappingProcessorUtils.process(MappingProcessorU tils.java:112)
at org.compass.core.config.process.MappingProcessorUtils.addInternalId(MappingProc essorUtils.java:105)
at org.compass.core.config.process.LateBindingOsemMappingProcessor.secondPassJustR eference(LateBindingOsemMappingProcessor.java:212)
at org.compass.core.config.process.LateBindingOsemMappingProcessor.secondPass(Late BindingOsemMappingProcessor.java:165)
at org.compass.core.config.process.LateBindingOsemMappingProcessor.secondPass(Late BindingOsemMappingProcessor.java:120)
at org.compass.core.config.process.LateBindingOsemMappingProcessor.secondPass(Late BindingOsemMappingProcessor.java:101)
at org.compass.core.config.process.LateBindingOsemMappingProcessor.process(LateBin dingOsemMappingProcessor.java:83)
at org.compass.core.config.CompassMappingProcessor.process(CompassMappingProcessor .java:57)
at org.compass.core.config.CompassConfiguration.buildCompass(CompassConfiguration. java:225)

And sometimes don't

I've done some digging in the source code and found that in class BasicPropertyAccessor in method: private static Method getterMethod(Class theClass, String propertyName) You iterate trough the method table of the class, and everything depends on this table. As You can see below:

public int test.compass.method.TestClass.hashCode()
public boolean test.compass.method.TestClass.equals(java.lang.Object)
public java.lang.String test.compass.method.TestClass.getId()
public java.io.Serializable test.compass.method.TestClass.getId()
public test.compass.method.TestClass test.compass.method.TestClass.setId(java.lang.String)
public final native java.lang.Class<?> java.lang.Object.getClass()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public java.lang.String java.lang.Object.toString()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

there are two getId methods returning two different objects. If getter for string is first Compass builds itself if Serializable is first it throws an exception.
A wonder why don't You use this method:
Link: http://java.sun.com/javase/6/docs/api/java/ lang/Class.html#getMethod(java.lang.String,%20java.lang.Class...) to find required method. it would be faster than iterating on table of 9 or more methods even considering exceptions catching.
I think it would solve the problem.

WALKAROUND:
Defining a @SearchableId(accessor = "property", converter = "string") on a method in subclass solves the problem.



 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Piotr Zieleziński added a comment - 29/Feb/08 09:17 AM
I'll try to find the test You mention on forum some time around next week when I find some time (a dead line is coming

BTW.
I've created a test of my own and it passed too.
But when I debugged BasicPropertyAccessor around 262 line the method table contained duplicated methods for getId() in my case.
You could put a break point there and see for Your self the methods in the table.

In my case this bug occurred when I added hashCode() and equals() methods to my domain class. Without them everything worked fine.