#53 custom property value is null

open
nobody
API (15)
8
2014-08-15
2011-03-17
Mac
No

custom property value is null

Hi

I working on a project using olap4j and Mondrian. I have a dimension 'Region', with 3 levels and 2 properties on the first level. Mondrian schema snipped below:

<Level name="Country" column="country_code" type="String" uniqueMembers="false">
<Property name="CountryName" column="country_name" type="String"/>
<Property name="Country ISO" column="country_iso" type="String"/>
</Level>
<Level name="Region Name" column="region_name" type="String" uniqueMembers="false"/>
<Level name="Dial Code" column="dial_code" type="String" uniqueMembers="true"/>

I wan to display the property of the Country level i.e. CountryName and Country ISO
When I use jPivot, all works. I can view Country (by code) and I can display property values.

When I try to do the same in code I always get null as the property value.

test code:

Cube cube = getCube();
Dimension dimension = cube.getDimensions().get(dimensionName);

for (Member m : dimension.getDefaultHierarchy().getDefaultMember().getChildMembers()) {
for (Property p : m.getProperties()) {
System.out.println(m.getName() + " : " + p.getName() + " : " + m.getPropertyFormattedValue(p));
}
}

Using m.getPropertyValue(p) also returns null

output:

61 : CATALOG_NAME : af
61 : SCHEMA_NAME : af
61 : CUBE_NAME : CDR
61 : DIMENSION_UNIQUE_NAME : [Region]
61 : HIERARCHY_UNIQUE_NAME : [Region]
61 : LEVEL_UNIQUE_NAME : [Region].[Country]
61 : LEVEL_NUMBER : 1
61 : MEMBER_ORDINAL : 114519
61 : MEMBER_NAME : 61
61 : MEMBER_UNIQUE_NAME : [Region].[61]
61 : MEMBER_TYPE : REGULAR
61 : MEMBER_GUID : null
61 : MEMBER_CAPTION : 61
61 : CHILDREN_CARDINALITY : 20
61 : PARENT_LEVEL : 0
61 : PARENT_UNIQUE_NAME : [Region].[All Regions]
61 : PARENT_COUNT : 1
61 : DESCRIPTION :
61 : $visible : null
61 : MEMBER_KEY : null
61 : IS_PLACEHOLDERMEMBER : null
61 : IS_DATAMEMBER : null
61 : DEPTH : 1
61 : DISPLAY_INFO : null
61 : VALUE : null
61 : CountryName : null
61 : Country ISO : null

Using Mondrian v 3.2.1.13885
olap4j olap4j-0.9.9-SNAPSHOT (had the same problem on olap4j-0.9.8.343)

Good work guys.
Thanks

Discussion

  • Sergio

    Sergio - 2011-04-05

    Hello,

    I am developing a project to access to Mondrian sources with OLAP4J and I have got the same problem.

    I am working directly with the mondrian examples (release 3.2), and I have got problems with queries like:

    [i]"SELECT [Measures].members ON COLUMNS,
    [Store].members dimension properties [Store].[Store Name].[Store Manager] ON ROWS FROM [Sales Ragged]"
    [/i]

    If I execute this query from JPivot, I can see the correct values of members from [Store] hierarchy and the measures, but any about the desired dimension properties. Although, if I click on the button "Mostrar propiedades" (in my Spanish version, "Show properties in english version I suppose), then all the properties are shown (I attach a capture).

    For debug, I try to get the properties of members in this way:

        cellSet = statement.executeOlapQuery(olapQuery);
    ListIterator<Position> positions = cellSet.getAxes().get(1).iterator();
    while(positions.hasNext() && !stopRequested) { 
        Position cellSetRow = positions.next();
    
        for (Member member : cellSetRow.getMembers()) {
    
                NamedList<Property> properties = member.getLevel().getProperties();                         
           if (properties!=null) {
              System.out.println("\n*** Properties of " + member.getName() + " *** ");
                  for (Property p : properties) {
              System.out.println("PropertyName -> " + p.getName()  +  " VALUE = " + member.getPropertyValue(p));
              }
            }                       
        }
         .....
         }
    

    Well, I downloaded the olap4j source code (0.9.8 version) and I can see that the method "getPropertyValue" of the member (an XmlaOlap4jPositionMember instance) firstly tries to get the property from a map named "propertyValues". This map HAS GOT the desired property with the correct value!, but unfortunately the "containsKey" method does not match with the property parameter, because the map has got instances of XmlaOlap4jCellSetMemberProperty, and the property parameter is an instance of XmlaOlap4jProperty :-S. I do not know if this is correct, but it seems a bit strange.
    Finally, the method tries to get the property from an encapsulated member (instance of XmlaOlap4jMember) which has got a properties map, but this map is empty.

    I think this is the same problem that "mac-b" has got.

    Is there some workaround?, or do you think to solve this issue?

    Many thanks in advanced.

     
  • Felix Saz

    Felix Saz - 2011-05-04

    These changes apparently fixes the problem by connecting to 'Microsoft Analysis Services'

    Index: src/org/olap4j/driver/xmla/XmlaOlap4jProperty.java

    --- src/org/olap4j/driver/xmla/XmlaOlap4jProperty.java (revision 452)
    +++ src/org/olap4j/driver/xmla/XmlaOlap4jProperty.java (working copy)
    @@ -62,11 +62,14 @@
    public ContentType getContentType() {
    return contentType;
    }
    + public int hashCode() {
    + String s=name+((uniqueName!=null)?uniqueName:"" );
    + return s.hashCode();
    + }

     public boolean equals(Object obj) {
         return (obj instanceof XmlaOlap4jProperty)
    
    • && this.uniqueName.equals(
    • ((XmlaOlap4jProperty) obj).getUniqueName());
    • && this.hashCode()==((XmlaOlap4jProperty) obj).hashCode();
      }
      }

    Index: src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java

    --- src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java (revision 452)
    +++ src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java (working copy)
    @@ -31,6 +31,7 @@
    import java.util.Map.;
    import java.util.regex.
    ;

    +
    /
    * Implementation of {@link org.olap4j.OlapConnection}
    * for XML/A providers.
    @@ -1534,7 +1535,47 @@
    childrenCardinality, memberOrdinal, map);
    list.add(member);
    }
    -
    +

    + /

    + * Copyright 2004-2005 The Apache Software Foundation or its licensors,
    + * as applicable.
    +
    + * Licensed under the Apache License, Version 2.0 (the "License");
    + * you may not use this file except in compliance with the License.
    + * You may obtain a copy of the License at
    +

    + * http://www.apache.org/licenses/LICENSE-2.0
    +
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + *
    + * package org.apache.jackrabbit.core.util;
    + * src: http://www.koders.com/java/fid509B4903EAA13EA313DEF35561DFCA559F8A2F29.aspx?s=b1.4
    + * @param name
    + * @return
    +
    /
    + public static String decode(String name) {
    + // quick check
    + if (name==null || name.indexOf("_x") < 0) {
    + // not encoded
    + return name;
    + }
    + StringBuffer decoded = new StringBuffer();
    + Matcher m = ENCODE_PATTERN.matcher(name);
    + while (m.find()) {
    + m.appendReplacement(decoded, Character.toString((char) Integer.parseInt(m.group().substring(2, 6), 16)));
    + }
    + m.appendTail(decoded);
    + return decoded.toString();
    + }
    + / Pattern on an encoded character /
    + private static final Pattern ENCODE_PATTERN = Pattern.compile("x\p{XDigit}{4}");
    + //End The Apache Copyright
    + /***********
    /
    +
    private void addUserDefinedDimensionProperties(
    Element row,
    XmlaOlap4jLevel level,
    @@ -1547,9 +1588,9 @@
    continue;
    }
    for (Property property : level.getProperties()) {
    + String localName=decode(node.getLocalName());
    if (property instanceof XmlaOlap4jProperty
    - && property.getName().equalsIgnoreCase(
    - node.getLocalName()))
    + && property.getName().equalsIgnoreCase(localName))
    {
    map.put(property, node.getTextContent());
    }

     
  • Sergio

    Sergio - 2011-06-23

    Hello fsaz,

    I have tried your suggested changes to access to a mondrian server through XMLA driver and it is not still resolved the problem.

    The scenary and the results are the same I posted two months ago.

    Any idea, workaround or future solution?

    Thanks.

     
  • Sergio

    Sergio - 2011-06-23

    Another proof I have done with mondrian examples.

    I am trying to get the [Store Manager] property, so I am executing a query like this:

    SELECT [Store].[Store Name].MEMBERS DIMENSION PROPERTIES [Store].[Store Manager] ON ROWS,
    [Measures].members ON COLUMNS
    FROM [Store]

    Well, accesing to the properties like I show in the code below (this the unique way I found to get properties from Java code), the "UNIQUENAME" for the desired property is "[Store].[Store_x0020_Manager]", instead of "[Store].[Store Manager]"

    But, for me, the major problem is that if you try to get the property with this uniquename in the MDX sentence, the results have not got the property value, this is null.

    SELECT [Store].[Store Name].MEMBERS DIMENSION PROPERTIES [Store].[Store_x0020_Manager] ON ROWS,
    [Measures].members ON COLUMNS
    FROM [Store]

    I think this is a bug, If you put in your query the name [Store].[Store Manager], the returned value must have as name "[Store].[Store Manager]". Or, in the other hand, if the uniquename is [Store].[Store_x0020_Manager], you should can query for the property in the MDX with this uniquename.

    Please, if i am wrong or there is a better another way to get the properties, tell me.

    public class Sample {

    public static void main(String args[]) throws Exception {
    

    // String query = "SELECT [Store].[Store Name].MEMBERS DIMENSION PROPERTIES [Store].[Store_x0020_Manager] ON ROWS, "
    String query = "SELECT [Store].[Store Name].MEMBERS DIMENSION PROPERTIES [Store].[Store Manager] ON ROWS, "
    + " [Measures].members on columns "
    + " from [Store]";

        Class.forName("org.olap4j.driver.xmla.XmlaOlap4jDriver");
        Connection connection =
            DriverManager.getConnection(
                    "jdbc:xmla:"
                    + "Server=htt://myserver.com/mondrian/xmla;"
                    + "Catalog=FoodMart");
        OlapConnection olapConnection = ((OlapWrapper)connection).unwrap(OlapConnection.class);
        OlapStatement statement = olapConnection.createStatement();
        CellSet cellSet =
            statement.executeOlapQuery(query);
    
        for (Position row : cellSet.getAxes().get(1)) {
            for (Position column : cellSet.getAxes().get(0)) {
                cellSet.getAxes().get(1).getAxisMetaData().getProperties();
    
                for (Member member : row.getMembers()) {
                    System.out.println(member.getUniqueName());
    
                    for (Property prop : cellSet.getAxes().get(1).getAxisMetaData().getProperties()) {
                        System.out.println("\n\tName: " + prop.getName());
                        System.out.println("\tUniqueName: + " + prop.getUniqueName());
                        System.out.println("\tCaption: + " + prop.getCaption());                    
                        System.out.println("\tFormattedValue: " + member.getPropertyFormattedValue(prop));
                        System.out.println("\tValue: " + member.getPropertyValue(prop));                        
                    }
    
                }
                for (Member member : column.getMembers()) {
                    System.out.println(member.getUniqueName());
                }
                                final Cell cell = cellSet.getCell(column, row);
                System.out.println(cell.getFormattedValue());
    
            }
        }
    }
    

    }

     
  • Comment has been marked as spam. 
    Undo

    You can see all pending comments posted by this user  here

    Anonymous - 2011-09-28

    I trace the problem for the whole afternoon and found the root cause comes from the missing "equal" method in class "XmlaOlap4jCellSetMemberProperty" which causes the mehtod "Map.containKey" fails to lookup the correct user-defined property..

    Below is my fix (Beta version)

    ----------------------------XmlaOlap4jCellSetMemberProperty.java------------------------------

    public boolean equals(Object obj) {
        if(obj instanceof Property)
        {
            return getName().equals(((Property)obj).getName());
        }
        return false;
    }
    
     
  • Julian Hyde

    Julian Hyde - 2011-09-28

    Up priority since patch is supplied.

     
  • Vladislav Malicevic

    Hi all,
    There is still no solution to this issue (patches are not working). Is there any progress? Is there something we can help you with?

    Cheers!
    Vlado

     
  • Luc Boudreau

    Luc Boudreau - 2013-12-23

    Hi Vlad,

    No solution yet. I've just read the code and it's highly likely to create bugs. The methods for hashCode and equals are both missing. Also the report above about having both XmlaProperties and XmlaOlap4jCellSetMemberProperty in the same collection is worrying.

     

Log in to post a comment.