-->
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.  [ 14 posts ] 
Author Message
 Post subject: Possible Memory Leak
PostPosted: Fri Apr 21, 2006 8:57 pm 
Newbie

Joined: Thu Oct 13, 2005 12:04 am
Posts: 7
Hibernate version: 3.1.2

Name and version of the database you are using: MySQL 5.0

Hi Everybody,

I have tried to locate a very subtle leak in my application for a little while now. I believe that the problem is related to the hibernate Native SQL queries and the QueryPlanCache.

First here is the jmap histogram from my production server (abbreviated):
Code:
Object Histogram:

Size    Count   Class description
-------------------------------------------------------
256713296       567805  char[]
97635840        3055506 java.lang.String[]
32430792        186691  java.util.HashMap$Entry[]
24671952        55143   java.lang.String[][]
23471520        586788  java.lang.String
22764592        15942   byte[]
15836608        88492   * ConstMethodKlass
13260376        126508  java.lang.Object[]
11470016        179219  java.util.HashMap
11192400        16479   int[]
11057760        230370  java.util.HashMap$Entry
10249120        7952    * ConstantPoolKlass
9211328 88492   * MethodKlass
6972736 108949  org.apache.commons.collections.ReferenceMap$SoftRef
6955736 134766  * SymbolKlass
6128512 7100    * ConstantPoolCacheKlass
6097840 54445   org.hibernate.loader.custom.SQLCustomQuery
5482144 7952    * InstanceKlassKlass


Again, this isn't the full dump but one of the first things that jumps out to me is the org.hibernate.loader.custom.SQLCustomQuery.

I ran the application through JProfiler and found that indeed the SQLCustomQuery never seems to be released. After looking at the references in the heap it looks like the query is rooted in the QueryPlanCache. Every time I hit a page that has a custom SQL query it adds to the collection (which just keeps aggregating objects and never collecting them).

I wouldn't be so worried about it but the SQLCustomQuery itself is nested under a number of SequencedHashMap$Entry objects (and it is pretty deep) so I also have a bunch of these objects around. I think this is why I have so many instances of org.apache.commons.collections.ReferenceMap$SoftRef and in fact why I have so many instances of other objects as above.

As I mentioned the leak is subtle and takes a few days to become an issue but it is certainly annoying.

I couldn't find any way to disable the QueryPlanCache either so it seems to me like my only option is to try to find a way to not use the native sql queries.

Any ideas?

TIA
Jarrod[/code]


Top
 Profile  
 
 Post subject: More confirmation
PostPosted: Thu Apr 27, 2006 11:54 am 
Newbie

Joined: Thu Oct 13, 2005 12:04 am
Posts: 7
Well, I refactored my schema a little bit so I wouldn't have to use native sql queries (we had a bitmask that we were using bitwise operations on which is not supported in HQL and really not in the ANSI-SQL 92 spec... shame). Anyway, when the native queries were indeed removed and after running for a couple of days the memory has disappeared. This indicates to me that there is indeed some kind of leak with the native sql queries and the query plan cache.

I will post a JIRA issue if somebody from the Hibernate teams tells me to do so.

All that being said if somebody is experiencing a memory leak in their hibernate app and they are using native sql queries try to modify your code to avoid the query and see if that fixes the problem because that seems to have worked for me.

Thanks,
Jarrod


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 20, 2006 3:06 pm 
Newbie

Joined: Tue Jun 21, 2005 1:02 pm
Posts: 12
I too ran into this problem. With native SQL quries, I encountered a memory leak surrounding the SQL parsing objects. This problem occurs in versions 3.1.1, 3.1.3, and 3.2.0-cr4. The problem does not occur in version 3.1.

Did the jira defect ever get entered for this problem? If so, could someone please give me the link to get to it?

Thanx,
Jim


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 20, 2006 7:46 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 7:19 pm
Posts: 2364
Location: Brisbane, Australia
JIRA is on the main page on the menu. IN anycase, here is the link.
http://www.hibernate.org/217.html


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 21, 2006 8:39 am 
Newbie

Joined: Tue Jun 21, 2005 1:02 pm
Posts: 12
David,
I didn't mean where is the link to Jira. I would like a link to the actual Jira defect (if there is one). My searches of Jira have not found this defect, so I figured I was just missing it.

Thanx,
Jim


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 21, 2006 9:00 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
i don't recall it have been reported.

report it in jira, but hopefully with a reproduciable test...thanks.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 21, 2006 9:14 am 
Newbie

Joined: Tue Jun 21, 2005 1:02 pm
Posts: 12
Max,
I have not, nor can I at this time, spent the time to come up with a simple and reproducible test case that I can upload. Would you still like me to enter the Jira defect anyway?

Thanx,
Jim


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 21, 2006 9:18 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
well if you don't have something that shows it leaking you probably won't see anyone trying to fix it.

so without a testcase then it won't make much sense to report it.

There were others that had apparently seen it - could you reproduce it standalone and not just embedded into your application code ?

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 21, 2006 10:59 am 
Newbie

Joined: Tue Jun 21, 2005 1:02 pm
Posts: 12
Max,
This is, unfortunately, the response I expected <sigh>. I can place enough detail in the defect to allow someone else to (probably) reproduce this problem, but it can take quite a bit of time to abstract the problem into simple test cases. I will place that detail here and leave the decision up to you as to whether a defect should be created.

Thanx,
Jim

Problem:
Memory leak with native SQL queries

Hibernate Versions:
3.1.1 and up (no leak in 3.1)

Detail:
When using native sql queries, a JProbe memory comparrison shows many org.hibernate.hql.ast.tree.IdentNode objects and their associated objects consuming memory. Running the same queries in version 3.1 of Hibernate does not show the same memory consumption problem. Also, when the same query is translated to hql, the memory consumption problem goes away (this is how I have worked around the problem).

The query listed below that I know causes the leak is very complex. I suspect that a more simple native sql query would also cause the same problem, but I have not tested this.

Query that causes the leak:
Code:
SELECT ud.BASE_DATA_ID id
FROM PORTAL_PAGE ud
JOIN BASE_DATA bd ON bd.BASE_DATA_ID = ud.BASE_DATA_ID
inner join NLS_DATA  name on ud.BASE_DATA_ID = name.NAME_BASE_DATA_ID
inner join NLS_DATA  description on ud.BASE_DATA_ID = description.DESCRIPTION_BASE_DATA_ID
WHERE ( ( (UPPER(name.STR_VALUE_TXT) LIKE UPPER(:searchString))
   AND  ( (UPPER(name.LOCALE_TXT) = UPPER(:variant))
      OR  ((UPPER(name.LOCALE_TXT) = UPPER(:country))
       AND (ud.BASE_DATA_ID NOT IN (select ud2.BASE_DATA_ID
             FROM USER_DATA  ud2
             inner join NLS_DATA  name2 on ud2.BASE_DATA_ID = name2.NAME_BASE_DATA_ID
             WHERE (ud.BASE_DATA_ID = ud2.BASE_DATA_ID)
             AND (UPPER(name2.LOCALE_TXT) = UPPER(:variant)))))

      OR  ((UPPER(name.LOCALE_TXT) = UPPER(:language))
       AND (ud.BASE_DATA_ID NOT IN (select ud2.BASE_DATA_ID
           FROM USER_DATA  ud2
           inner join NLS_DATA  name2 on ud2.BASE_DATA_ID = name2.NAME_BASE_DATA_ID
           WHERE (ud.BASE_DATA_ID = ud2.BASE_DATA_ID)
             AND ( (UPPER(name2.LOCALE_TXT) = UPPER(:variant)) OR (UPPER(name2.LOCALE_TXT) = UPPER(:country)) ) )))

      OR  ((name.NAME_POS_NO = 0)
       AND (ud.BASE_DATA_ID NOT IN (select ud2.BASE_DATA_ID
           FROM USER_DATA  ud2
           inner join NLS_DATA  name2 on ud2.BASE_DATA_ID = name2.NAME_BASE_DATA_ID
           WHERE (ud.BASE_DATA_ID = ud2.BASE_DATA_ID)
             AND ( (UPPER(name2.LOCALE_TXT) = UPPER(:variant)) OR (UPPER(name2.LOCALE_TXT) = UPPER(:country)) OR  (UPPER(name2.LOCALE_TXT) = UPPER(:language)) ) )))) )

OR ( (UPPER(description.STR_VALUE_TXT) LIKE UPPER(:searchString))
   AND  ( (UPPER(description.LOCALE_TXT) = UPPER(:variant))
      OR  ((UPPER(description.LOCALE_TXT) = UPPER(:country))
       AND (ud.BASE_DATA_ID NOT IN (select ud2.BASE_DATA_ID
             FROM USER_DATA  ud2
             inner join NLS_DATA  description2 on ud2.BASE_DATA_ID = description2.DESCRIPTION_BASE_DATA_ID
             WHERE (ud.BASE_DATA_ID = ud2.BASE_DATA_ID)
             AND (UPPER(description2.LOCALE_TXT) = UPPER(:variant)))))

      OR  ((UPPER(description.LOCALE_TXT) = UPPER(:language))
       AND (ud.BASE_DATA_ID NOT IN (select ud2.BASE_DATA_ID
           FROM USER_DATA  ud2
           inner join NLS_DATA  description2 on ud2.BASE_DATA_ID = description2.DESCRIPTION_BASE_DATA_ID
           WHERE (ud.BASE_DATA_ID = ud2.BASE_DATA_ID)
             AND ( (UPPER(description2.LOCALE_TXT) = UPPER(:variant)) OR (UPPER(description2.LOCALE_TXT) = UPPER(:country)) ) )))

      OR  ((description.DESCRIPTION_POS_NO = 0)
       AND (ud.BASE_DATA_ID NOT IN (select ud2.BASE_DATA_ID
           FROM USER_DATA  ud2
           inner join NLS_DATA  description2 on ud2.BASE_DATA_ID = description2.DESCRIPTION_BASE_DATA_ID
           WHERE (ud.BASE_DATA_ID = ud2.BASE_DATA_ID)
             AND ( (UPPER(description2.LOCALE_TXT) = UPPER(:variant)) OR (UPPER(description2.LOCALE_TXT) = UPPER(:country)) OR  (UPPER(description2.LOCALE_TXT) = UPPER(:language)) ) )))) ) )
AND ( (bd.OMR_LOCATION_TXT in ("group1")) )


Relevant Table Structure:
Code:
create table BASE_DATA (BASE_DATA_ID bigint not null, OBJECT_VERSION_NO bigint not null, CREATED_ON_DTTM timestamp not null, MODIFIED_ON_DTTM timestamp not null, CREATED_BY_NM varchar(255) not null, MODIFIED_BY_NM varchar(255) not null, OMR_LOCATION_TXT varchar(1024) not null, primary key (BASE_DATA_ID));

create table NLS_DATA (NLS_DATA_ID bigint not null, OBJECT_VERSION_NO bigint not null, LOCALE_TXT varchar(8), STR_VALUE_TXT varchar(8000), KEYWORD_ID bigint, KEYWORD_POS_NO integer, PORTLET_NAME_ID bigint, PORTLET_NAME_POS_NO integer, PORTLET_DESCRIPTION_ID bigint, PORTLET_DESCRIPTION_POS_NO integer, NAME_BASE_DATA_ID bigint, NAME_POS_NO integer, DESCRIPTION_BASE_DATA_ID bigint, DESCRIPTION_POS_NO integer, NOTES_BASE_DATA_ID bigint, NOTES_POS_NO integer, primary key (NLS_DATA_ID));

create table PORTAL_PAGE (BASE_DATA_ID bigint not null, PAGE_RANK_NO integer not null, LAYOUT_TYPE_CD integer not null, SHARE_TYPE_CD integer not null, MIME_TYPE_TXT varchar(50), TEMPLATE_BASE_DATA_ID bigint, LAYOUT_BASE_DATA_ID bigint, primary key (BASE_DATA_ID));

create table USER_DATA (BASE_DATA_ID bigint not null, primary key (BASE_DATA_ID));


Relavent Mapping Files:
BaseData.hbm.xml
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Copyright (c) 2006 by SAS Institute Inc., Cary, NC 27513 USA. All Rights Reserved. -->
<hibernate-mapping package="com.sas.portal.data.model.hibernate">
    <class name="BaseData" table="BASE_DATA">
        <meta attribute="class-description">
            The BaseData class provides some common data for objects.
        </meta>
        <meta attribute="class-code">
            <![CDATA[               
             private static final long serialVersionUID = -5605415560820797542L;
            
                public static final String  READ_SECURITY_FILTER        =   "readSecurityFilter";
                public static final String  PARAM_SESSION_ID                =   "sessionId";

                public String toString() {
                    String className = getClass().getName();
                    className = className.substring(className.lastIndexOf('.')+1);
                    return className + ":" + getId();
                }
            ]]>
        </meta>


        <cache usage="read-write" />

        <!-- ID -->
        <id name="id" column="BASE_DATA_ID" type="long">
            <meta attribute="scope-set">public</meta>
            <generator class="native"/>
        </id>

      <version column="OBJECT_VERSION_NO" name="version" type="long">
            <meta attribute="scope-set">public</meta>
        </version>

        <!-- Attributes -->
        <property name="createdOn" column="CREATED_ON_DTTM" type="timestamp" not-null="true">
            <meta attribute="field-description">The timestamp that the data was created on.</meta>
        </property>
        <property name="modifiedOn" column="MODIFIED_ON_DTTM" type="timestamp" not-null="true">
            <meta attribute="field-description">The timestamp that the data was last modified on.</meta>
        </property>
      <property name="createdBy" column="CREATED_BY_NM" type="string" not-null="true">
         <meta attribute="field-description">The userid of the creating user</meta>
      </property>
      <property name="modifiedBy" column="MODIFIED_BY_NM" type="string" not-null="true">
         <meta attribute="field-description">The userid of the last modifying user</meta>
      </property>
        <property name="location" column="OMR_LOCATION_TXT" type="string" length="1024" not-null="true">
            <meta attribute="field-description">
                The location that this data is conceptually stored in.  The value of this string is the SBIP URL of
                the Portal Data OMR object.
            </meta>
        </property>

<!--
        <filter  name="readSecurityFilter"
                    condition="(select perm from BASE_DATA_PERMISSIONS(:sessionId, BASE_DATA_ID, 1)) = 1" />
-->                   
    </class>
    <filter-def name="readSecurityFilter">
        <filter-param name="sessionId" type="string" />
    </filter-def>
</hibernate-mapping>


NlsData.hbm.xml
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Copyright (c) 2006 by SAS Institute Inc., Cary, NC 27513 USA. All Rights Reserved. -->
<hibernate-mapping package="com.sas.portal.data.model.hibernate">
    <class name="NlsData" table="NLS_DATA">
        <meta attribute="class-description">
            The NlsData class provides internationalization of all user entered
            strings in the Portal..
        </meta>
        <meta attribute="class-code">
            <![CDATA[               
                private static final long serialVersionUID = -9108781422229084969L;

                /* These constants need to be kept in sync with the lengths if the xml below */
                public static final int         LOCALE_MAX_LENGTH                    =   8;
                public static final int         VALUE_MAX_LENGTH                      =   8000;
            
                public String toString() {
                    String className = getClass().getName();
                    className = className.substring(className.lastIndexOf('.')+1);
                    return className + ":" + getId() + ":" + getLocale() + ":" + getValue();
                }
            ]]>
        </meta>


        <cache usage="read-write" />

        <!-- ID -->
        <id name="id" column="NLS_DATA_ID" type="long">
            <meta attribute="scope-set">public</meta>
            <generator class="native"/>
        </id>

      <version column="OBJECT_VERSION_NO" name="version" type="long">
            <meta attribute="scope-set">public</meta>
        </version>

        <!-- Attributes -->
        <property name="locale" column="LOCALE_TXT" type="string" length="8">
            <meta attribute="field-description">
                The locale of this internationalized string.
            </meta>
        </property>
        <property name="value" column="STR_VALUE_TXT" type="string" length="8000">
            <meta attribute="field-description">
                The internationalized string.
            </meta>
        </property>
    </class>
</hibernate-mapping>


PortalPage.hbm.xml
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Copyright (c) 2006 by SAS Institute Inc., Cary, NC 27513 USA. All Rights Reserved. -->
<hibernate-mapping package="com.sas.portal.data.model.hibernate">
    <joined-subclass extends="UserData" name="PortalPage" table="PORTAL_PAGE">
        <meta attribute="class-description">
            The PortalPage class represents a page in the Portal.
        </meta>

        <meta attribute="extra-import">java.util.ArrayList</meta>

        <meta attribute="class-code">
            <![CDATA[
             private static final long serialVersionUID = -4158481172144981203L;

                public static final int         SHARE_TYPE_AVAILABLE  =   0;
                public static final int         SHARE_TYPE_DEFAULT  =   1;
                public static final int         SHARE_TYPE_STICKY  =   2;

                public static final int         LAYOUT_TYPE_COLUMN  =   0;
                public static final int         LAYOUT_TYPE_GRID        =   1;
                public static final int         LAYOUT_TYPE_CUSTOM  =   2;
            public static final int         LAYOUT_TYPE_MAXIMIZED = 3;
            
                public static final int DEFAULT_PAGE_RANK = 100;

                public static final String DEFAULT_SHARE_TAG = "Default";
                public static final String STICKY_SHARE_TAG = "Sticky";
                public static final String AVAILABLE_SHARE_TAG = "Available";

                /* These constants need to be kept in sync with the lengths if the xml below */
                public static final int         MIME_TYPE_MAX_LENGTH                      =   50;

                public void addPortletList (PortletList portletList) {
                    if (portletList != null) {
                        List portletLists = getPortletLists();
                        if (portletLists == null) {
                            portletLists = new ArrayList();
                        }
                        portletLists.add(portletList);
                        setPortletLists(portletLists);
                        portletList.setPage(this);
                    }
                }

                public String getShareTypeString() {
                    String retval = "";
                    switch (getShareType()) {
                    case SHARE_TYPE_DEFAULT:
                        retval = DEFAULT_SHARE_TAG;
                        break;
                    case SHARE_TYPE_STICKY:
                        retval = STICKY_SHARE_TAG;
                        break;
                    case SHARE_TYPE_AVAILABLE:
                    default:
                        retval = AVAILABLE_SHARE_TAG;
                        break;
                    }
           
                    return retval;
                }

                public void setShareTypeString(String shareTypeString) {
                    if (shareTypeString.equals(DEFAULT_SHARE_TAG)) {
                        setShareType(SHARE_TYPE_DEFAULT);
                    } else if (shareTypeString.equals(STICKY_SHARE_TAG)) {
                        setShareType(SHARE_TYPE_STICKY);
                    } else {
                        setShareType(SHARE_TYPE_AVAILABLE);
                    }
                }
            ]]>
        </meta>

        <!-- Key -->
        <key column="BASE_DATA_ID" />

        <!-- Attributes -->
        <property name="pageRank" column="PAGE_RANK_NO" type="int" not-null="true">
            <meta attribute="field-description">
                Page Rank, if the user has not chosen a specific order in which to show the page
            </meta>
        </property>
        <property name="layoutType" column="LAYOUT_TYPE_CD" type="int" not-null="true">
            <meta attribute="field-description">
                LayoutType for this page.  The value should be one of the constants defined in this class.
            </meta>
        </property>
        <property name="shareType" column="SHARE_TYPE_CD" type="int" not-null="true">
            <meta attribute="field-description">
                Share type for this page.  The value should be one of the constants defined in this class.
            </meta>
        </property>
      
      <property name="mimeType" column="MIME_TYPE_TXT" type="string" length="50">
         <meta attribute="field-description">
            HTTP mime-type for this page
         </meta>
      </property>

        <!-- Associations -->
        <list name="portletLists" lazy="true" fetch="select" cascade="all-delete-orphan">
            <meta attribute="field-description">The ordered list of portlet lists defined for this page.</meta>
            <key column="PAGE_BASE_DATA_ID"/>
            <index column="POSITION_IN_PORTLET_LIST_NO" />
            <one-to-many class="com.sas.portal.data.model.hibernate.PortletList" />
        </list>
      <!-- <many-to-one name="templatePage" column="TEMPLATE_BASE_DATA_ID" class="com.sas.portal.data.model.hibernate.TemplatePortalPage" fetch="select" not-null="false" /> -->
        <!--  <many-to-one name="layoutTemplate" column="LAYOUT_BASE_DATA_ID" class="com.sas.portal.data.model.hibernate.LayoutTemplate" fetch="select" not-null="false" /> -->
        <property name="templatePageId" column="TEMPLATE_BASE_DATA_ID" type="long">
            <meta attribute="field-description">
                The id of the template page for this page.  By specifying an id instead of
                a many-to-one for the object, we can facilitate a weak link between the 2
                objects.  We can then manipulate the referenced object (delete) without
                having to moddify this object.
            </meta>
        </property>
        <property name="layoutTemplateId" column="LAYOUT_BASE_DATA_ID" type="long">
            <meta attribute="field-description">
                The id of the layout template for this page.  By specifying an id instead of
                a many-to-one for the object, we can facilitate a weak link between the 2
                objects.  We can then manipulate the referenced object (delete) without
                having to moddify this object.
            </meta>
        </property>
        <list name="columnWidths" cascade="all-delete-orphan" lazy="true" fetch="select" table="PAGE_COLUMN_WIDTHS">
            <meta attribute="field-description">
                Provides an ordered list of column widths.  The number of columns will be determined
                by the length of this list.  This field is not used for custom layout.
            </meta>
            <cache usage="read-write" />
            <key column="PAGE_BASE_DATA_ID"/>
            <index column="POSITION_IN_COLUMN_LIST_NO" />
            <element column="COLUMN_WIDTH_NO" type="integer" />
        </list>
    </joined-subclass>
</hibernate-mapping>


UserData.hbm.xml
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Copyright (c) 2006 by SAS Institute Inc., Cary, NC 27513 USA. All Rights Reserved. -->
<hibernate-mapping package="com.sas.portal.data.model.hibernate">
    <joined-subclass extends="BaseData" name="UserData" table="USER_DATA">
        <meta attribute="class-description">
            The UserData class provides some base data and associations for objects.
            UserData is used for objects typically created and/or manipulated by the user.
        </meta>
        <meta attribute="extra-import">java.util.Locale</meta>
        <meta attribute="extra-import">java.util.Set</meta>
        <meta attribute="extra-import">java.util.Iterator</meta>
        <meta attribute="class-code">
            <![CDATA[
             private static final long serialVersionUID = 8292663888938139975L;

                public String toString() {
                    return super.toString() + ":" + getNlsName(Locale.getDefault());
                }

                public void putNlsName(Locale locale, String name) {
                    putNlsName(locale.toString(), name);
                }

                public void putNlsName(String locale, String name) {
                    // Get the list of nls names
                    List nlsNames = getNlsName();
                    if (nlsNames == null) {
                        nlsNames = new java.util.ArrayList();
                    }
                   
                    // Add the string
                    putNlsString(nlsNames, locale, name);
                   
                    // Set the list back again
                    setNlsName(nlsNames);
                }

                public void removeNlsName(Locale locale) {
                    List names = getNlsName();
                    if (names != null) {
                        removeLocaleEntry(names, locale.toString());
                        setNlsName(names);
                    }

                }

                public String getNlsName(Locale locale) {
                    // Get the string from the map based on the locale
                    List nlsNames = getNlsName();
                    return findNlsValue(nlsNames, locale);
                }

                public void putNlsDescription(Locale locale, String description) {
                    putNlsDescription(locale.toString(), description);
                }

                public void putNlsDescription(String locale, String description) {
                    // Get the map for the nls descriptions
                    List nlsDescriptions = getNlsDescription();
                    if (nlsDescriptions == null) {
                        nlsDescriptions = new java.util.ArrayList();
                    }

                    // Add the string
                    putNlsString(nlsDescriptions, locale, description);
                   
                    // Set the list back again
                    setNlsDescription(nlsDescriptions);
                }

                public void removeNlsDescription(Locale locale) {
                    List nlsDescriptions = getNlsDescription();
                    if(nlsDescriptions != null) {
                        removeLocaleEntry(nlsDescriptions, locale.toString());
                        setNlsDescription(nlsDescriptions);
                    }
                }

                public String getNlsDescription(Locale locale) {
                    // Get the string from the map based on the locale
                    List nlsDescriptions = getNlsDescription();
                    return findNlsValue(nlsDescriptions, locale);
                }

                public void addKeyword(Keyword keyword) {
                    if (keyword != null) {
                        Set keywords = getKeywords();
                        if (keywords == null) {
                            keywords = new java.util.HashSet();
                        }
                        keywords.add(keyword);
                        setKeywords(keywords);
                        keyword.setUserData(this);
                    }
                }

                public void removeKeyword(Keyword keyword) {
                    if(keyword != null) {
                        if(getKeywords() != null) {
                            if(getKeywords().remove(keyword)) {
                                keyword.setUserData(null);
                            }
                        }
                    }
                }

                public static String findNlsValue(List values, Locale locale) {
                    if(values == null || locale == null || values.size() == 0)
                        return null;
                    String retval = null;
                    String searchKey = null;
                    boolean useVariant = locale.getVariant() != null;
                    boolean useCountry = locale.getCountry() != null;

                    // First try locale passed in
                    if(useVariant) {
                        searchKey = locale.getLanguage() + "_" + locale.getCountry() + "_" +
                            locale.getVariant();
                        retval = getNlsString(values, searchKey);
                        if(retval != null) {
                            return retval;
                        }
                    }
                    if(useCountry) {
                        searchKey = locale.getLanguage() + "_" + locale.getCountry();
                        retval = getNlsString(values, searchKey);
                        if(retval != null) {
                            return retval;
                        }
                    }
                    searchKey = locale.getLanguage();
                    retval = getNlsString(values, searchKey);

                    // last ditch effort - just return the first one found
                    if(retval == null) {
                        NlsData data = (NlsData) values.get(0);
                        retval = data.getValue();
                    }
                   
                    return retval;
                }

                public static NlsData getLocaleEntry(List values, String locale) {
                    return getLocaleEntry(values, locale, false);
                }

                public static void removeLocaleEntry(List values, String locale) {
                    getLocaleEntry(values, locale, true);
                }
               
                public static String getNlsString(List values, String locale) {
                    String retval = null;
                   
                    NlsData data = getLocaleEntry(values, locale);
                    if (data != null) {
                        retval = data.getValue();
                    }

                    return retval;
                }
               
                public static void putNlsString(List values, String locale, String value) {
                    NlsData currentData = getLocaleEntry(values, locale);
                    if (currentData != null) {
                        currentData.setValue(value);
                    } else {
                        values.add(new NlsData(locale, value));
                    }
                }

                private static NlsData getLocaleEntry(List values, String locale, boolean removeIfFound) {
                    NlsData retval = null;

                    // Find an entry that matches the given locale                   
                    for (Iterator it = values.iterator(); it.hasNext(); ) {
                        NlsData data = (NlsData) it.next();
                        if (data.getLocale().equals(locale)) {
                            retval = data;
                            if (removeIfFound) {
                                it.remove();
                            }
                            break;
                        }
                    }

                    return retval;
                }
            ]]>
        </meta>

        <!-- Key -->
        <key column="BASE_DATA_ID" />

        <!-- Attributes -->

        <!--  How do we guarntee that a name is always provided? -->
        <list name="nlsName" cascade="all-delete-orphan" lazy="true" fetch="select" table="USER_DATA_NAMES">
            <meta attribute="field-description">
                The list of internationalized names.
            </meta>
            <meta attribute="scope-set">public</meta>
            <cache usage="read-write" />
            <key column="NAME_BASE_DATA_ID"/>
            <index column="NAME_POS_NO" />
            <one-to-many class="com.sas.portal.data.model.hibernate.NlsData" />
        </list>
        <list name="nlsDescription" cascade="all-delete-orphan" lazy="true" fetch="select" table="USER_DATA_DESCRIPTIONS">
            <meta attribute="field-description">
                The list of internationalized descriptions.
            </meta>
            <meta attribute="scope-set">public</meta>
            <cache usage="read-write" />
            <key column="DESCRIPTION_BASE_DATA_ID"/>
            <index column="DESCRIPTION_POS_NO" />
            <one-to-many class="com.sas.portal.data.model.hibernate.NlsData" />
        </list>

        <!-- Associations -->
        <set name="keywords" cascade="all-delete-orphan" lazy="true" >
            <meta attribute="field-description">
                A list of user defined keywords that can be used for searching.
            </meta>
            <cache usage="read-write" />
            <key column="USER_DATA_ID"/>
            <one-to-many class="com.sas.portal.data.model.hibernate.Keyword" />
        </set>
    </joined-subclass>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 21, 2006 11:16 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
jaweis wrote:
Max,
This is, unfortunately, the response I expected <sigh>.


I'm sorry, but what do you want me to do ? promise to hunt down a memory leak which cause is not known ? Sorry, but I can't hunt every ghost that is shown to me and there is much lower hanging jobs to work on ;)

btw. you say it is leaking IdentNode's which is weird since such things are not created when using native sql?!

But you are free to put it in jira, but I can't promise it will be taken up since it will probably just be marked as "incomplete" since there is no testcase on the other hand it could also be someone has enough time on his hand to look at it....but as you have just shown time is not an unlimited resource.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 21, 2006 3:17 pm 
Newbie

Joined: Tue Jun 21, 2005 1:02 pm
Posts: 12
Max,
The statement was not meant as "sour grapes" but as resigned acceptance. I fully understand that time is a very sparse and precious resource. I was just hoping that something as serious as a memory leak would get a little more traction.
We have worked around the problem by replacing our native SQL queries with hql queries instead. Maybe, in my copius spare time, I'll be able to circle back and come up with the test case you need. In the mean time, I just hope we don't need native SQL queries before this problem eventually gets fixed.

I do appreciate the time you have spent with me on this so far.

Thanx,
Jim


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 21, 2006 3:24 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
memory leaks does get our (and my) full attention as soon as there is just a hint of a reproducible testcase.

a testcase would be good to get. thanks.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 26, 2006 3:12 pm 
Newbie

Joined: Tue Sep 26, 2006 3:08 pm
Posts: 1
Location: Cork
Hi,

Has this been confirmed as a genuine memory leak? I am seeing something very similar, but I would like to know that iI'm not chasing a a red herring.

Thanks,
Jay


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 26, 2006 10:59 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
no, because noone have confirmed it yet...so if you have something concrete/specific then please bring it forward.

_________________
Max
Don't forget to rate


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 14 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.