betweenGo

Repository

DistributorSender startup warning

by on Dec.09, 2007, under Commerce, Repository

When starting ATG instances with the DCS module I will often see this warning.

DistributorSender No remote servers configured

This is because in the product catalog two item descriptors, media-internal-binary and media-internal-text, are configured to use the Dynamo content distributor system if it is available. This is documented in the Using Content Distribution with a SQL Content Repository section of the ATG Dynamo Programming Guide.

Since out of the box the Dynamo content distributor system is not configured we see the above warning. To turn it off simply set loggingWarning=false for the /atg/commerce/catalog/ContentDistributorPool component.

Share
Leave a Comment : more...

ClientLockManager useLockServer property is false warning

by on Dec.07, 2007, under Repository

In many ATG instances I will see this warning upon startup.

/atg/dynamo/service/ClientLockManager The useLockServer property of: /atg/dynamo/service/ClientLockManager is false and so global locking is disabled

As explained in the Enable the Repository Cache Lock Managers section of the Installation and Configuration Guide for DAS the ClientLockManager must be enabled if you are using locked mode caching anywhere in your SQL repository, which is typically the case in production when you are running more than one ATG server. The above warning is to inform the ATG administrator that currently the ClientLockManager is not enabled.

To enable it follow the instructions in the Configuring Lock Managers subsection of the Locked Caching section of the ATG Repository Guide.

On a single ATG instance environment you might still choose to setup the ClientLockManager and ServerLockManager just to get rid of this warning. To do this do the following.

  1. Enable ClientLockManager by creating localconfig/atg/dynamo/service/ClientLockManager.properties.lockServerAddress=localhost
    lockServerPort=9010
    useLockServer=true
  2. Start ServerLockManager by adding it to localconfig/atg/dynamo/service/Initial.properties.initialServices+=ServerLockManager

After doing this though you’ll see a warning like this.

/atg/dynamo/service/ServerLockManager No backup server is configured for Lock ServerCRAPBOOK-PRO/localhost:9010 It becomes Primary Server

So maybe in the end it’s better just to ignore the ClientLockManager warning, maybe even disable it. :-)

Share
Leave a Comment : more...

Debugging a Category’s Bad Child Products

by on Dec.07, 2007, under JDBC, Oracle, Repository

Today I was using the CategoryLookup droplet to find a category’s child products. However when I accessed the child products I would get this JDBC error.

java.lang.NullPointerException
at java.lang.String.(String.java:166)
at oracle.sql.CharacterSet.AL32UTF8ToString(CharacterSet.java:1517)

I realized my product data was corrupted. However this category had over 70 child products. The stack trace wasn’t telling me which one was corrupt and going through each child product to find out which one was corrupt was too painful.

I first queried the database to find all the child product ID’s.

SQL> select child_prd_id from dcs_cat_chldprd where category_id='cat101' order by sequence_num;

I then created a simple JHTML page which would query each child product and output which ones were corrupted.

<java>
final String [] product_ids = { "prod101", "prod102", "prod103" };

for (int ii = 0; ii < product_ids.length; ii++) {
out.print(ii + ". [" + product_ids[ii] + "] ");
try {
</java>
<droplet name="/atg/commerce/catalog/ProductLookup">
<param name="id" value="`product_ids[ii]`">
<oparam name="output">
<valueof param="element.displayName"/><br/>
</oparam>
</droplet>
<java>
} catch (RuntimeException exc) {
out.println(exc + "<br>");
}
}
</java>

Once I knew which child products were bad I removed their mappings to the category in dcs_cat_chldprd.

SQL> delete from dcs_cat_childprd where child_prd_id = 'prod102' and category_id='cat101';

Then I updated the sequence numbers so that they are all consecutive by moving the ones at the end to fill the holes created by the previous deletes.

SQL> update dcs_cat_childprd set sequence_num = 1 where child_prd_id = 'prod103' and category_id='cat101';

Share
Leave a Comment :, , more...

Viewing Expert-Level Information in the ACC

by on Dec.06, 2007, under ACC, Repository

William T. Sherman | FlickrSome information, such as properties and item descriptors, are marked as expert (i.e. expert=true) so that they are not displayed in the ACC unless you are an expert user.

For example:

<property name="type" data-type="enumerated" expert="true"/>

To display expert-level information in the ACC go to Tools > Preferences and select the "Show expert-level information" box.

ATG ACC Preferences

Note that this is not a "sticky" preference, i.e. you have to set it every time you restart the ACC.

Share
Leave a Comment : more...

Date and Timestamp Repository Data Types

by on Nov.17, 2007, under Repository

Today I noticed that my timestamp property was being saved with only the date information, not the time information. That is when I queried the corresponding column I saw something like this.

> select TO_CHAR(timestamp, 'yyyy-mm-dd hh24:mi:ss') from foo;

2007-11-17 00:00:00

The timestamp property was represented in Java using a Date class. I thought of switching it to a Timestamp class but was dubious because the only real difference is that the Timestamp class stores fractional seconds.

Then I looked at /atg/commerce/order/orderrepository.xml and the corresponding OrderImpl.java and realized that it used the timestamp repository data type while I was using the date repository date type. Since the Oracle column data type was also timestamp I found when I switched the repository data type the time information was also saved.

> select TO_CHAR(timestamp, 'yyyy-mm-dd hh24:mi:ss') from foo;

2007-11-17 20:03:00 

The moral of the story is to use the timestamp repository data type, not the date repository data type.

ATG has more documentation about this though it is not entirely true, i.e. you can use the Date Java class type with the timestamp SQL type.

Share
1 Comment : more...

ATG Repository User-Defined Property Types

by on Feb.07, 2007, under Repository

ATG allows one to use your own Java class data types for the properties of repository items. This is called User-Defined Property Types.

While working with these user-defined property types I learned a few things that are not explicitly documented.

  1. The source for atg.repository.FilePropertyDescriptor is supplied in the installation and it’s a good example for creating your own user-defined property type.
  2. To set values of properties in your Java class data type do two things.
    1. Configure the values of these properties using the attribute tag. For example:

      <property name="contentFile" property-type="atg.repository.FilePropertyDescriptor">
      <attribute name="pathNameProperty" value="contentFileName"/>
      </property>
    2. Access these attributes and set the corresponding properties in the setValue() method. Continuing with the above example:

      public void setValue(String pAttributeName, Object pValue) {
      super.setValue(pAttributeName, pValue);

      if (pValue == null || pAttributeName == null) return;
      if (pAttributeName.equalsIgnoreCase(PATH_NAME_PROPERTY))
      mPathNameProperty = pValue.toString();
      if (pAttributeName.equalsIgnoreCase(PATH_PREFIX))
      mPathPrefix = pValue.toString();
      }
  3. ATG’s documentation suggests it is not necessary to define the data-type attribute if you specify the type with the property-type attribute. However I found that sometimes ATG gets confused and that it is best practice to always set the data-type. So using the above example one would do this.

    <property name="contentFile" data-type="string" property-type="atg.repository.FilePropertyDescriptor">
    <attribute name="pathNameProperty" value="contentFileName"/>
    </property>
  4. Only one instance of your user-defined property type is ever instantiated. Even if your user-defined property type is used for multiple properties it will still only be instantiated once.
  5. The JavaDoc for ATG’s RepositoryPropertyDescriptor class, which one typically extends to create ones own user-defined property type, documents the getPropertyValue method like this: public java.lang.Object getPropertyValue(RepositoryItemImpl pItem, java.lang.Object pValue)

    The first argument is the instance of the repository item whose property you are defining.

    The second argument would be better named pCachedPropertyValue because it is the cached property value. If it is null then that means there is no cached value. If it is not null that means that in a previous call setPropertyValueInCache(this, yourvalue) was called. Unfortunately this cached value is not that useful because since only one instance of your user-defined property type is ever created, the cached value will be a global value.

    This cached value is cleared when invalidateCaches is called on the repository item.

    Here is what ATG support said about caching with User-Defined Property Types.

    I think user defined properties will not be cached so that will cause your code to be
    called several times. If you require some caching you would properly have to
    implement it in the code of the user-defined property.

    As a user defined property could return data from any external source that might get
    updated independently of the ATG application we can not really make a decision on
    what should be cached and what should be retrieved anew every single time.

    Kind regards,
    Olaf Doemer

  6. The property descriptor implements the Serializable interface so the developer must ensure that it is indeed serializable, i.e. all its members are serializable.
Share
5 Comments : more...

JDBC Optimization for Populating a Table

by on Aug.23, 2005, under JDBC, Repository

Today I was trying to determine how to optimize the populating of a table. I was using ATG Relational Views which took 3.5 minutes to add 6000 lines to a table.

After googling for awhile I learned how to do this using JDBC directly and was able to do the same populating in 0.14 minutes. That’s quite a performance improvement.

It would be interesting to contract the performance differences using ATG’s repository implementation but right now I am developing on ATG 4.5.1 so I can’t.

These are the links to the sites I used to educate me on PreparedStatement‘s and batching.

ONJava.com: An Introduction to JDBC, Part 3
JavaWorld.com: Overpower the Prepared Statement
PreciseJava.com: Best practices to improve performance in JDBC
DBA-oracle.com: Optimize Oracle INSERT performance

Share
Leave a Comment :, more...

user-defined property type gotcha’s

by on Jul.28, 2005, under ACC, Repository

When you create a user-defined property type there are two things to keep in mind.

  1. The user-defined property should be transient.
  2. The user-defined property must have a data-type defined or the item that contains this property will not be displayable in the ACC.

Here is an example of a user-defined property type.

<item-descriptor name="foo" display-property="name" display-name="Foo">

 <property name="bar" property-type="com.betweengo.Bar" data-type="string"/>

 <table name="foo" type="primary" id-column-names="id">
  <property name="id" data-type="string"/>
  <property name="name" column-names="name" data-type="string"/>
 </table>

</item-descriptor>

To learn more, User-Defined Property Types. Note that in the ATG documentation the example for the user-defined property does not define a data-type. This is probably a documentation bug.

Share
Leave a Comment : more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!