Tremend Tech Blog

"Software is a great combination between artistry and engineering. When you finally get done and get to appreciate what you have done it is like a part of yourself that you've put together." (Bill Gates)

Looking for software experts?

Need an expert advice on software development? Need consulting work done in time and at high standards? Tremend has the right solution for you.

We can provide expertise in:
  • high traffic and complex content website infrastructures
  • website development-advanced web programming with PHP, .NET, Java, Flash/Flex, Ajax

Our friends

Illegal attempt to associate a collection with two open sessions

March 5th, 2007 by Marius Hanganu

This is a minor problem, but it may help some of you out there. The error can occur from several reasons, but in this case it was due to bad use of cascade update. The exception I received was:

org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410)
at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:40)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123)

The problem was due to a misuse of cascade update in one of the mappings. The field was declared as follows:

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = “user_id”)
public User getAuthor() {
return author;
}

Removing the cascade = CascadeType.ALL fixed the problem.
Conclusion: carefully use cascade updates as it may get you into trouble. Use it when business logic requires it. In the example below there was no need for it, so removing it was both business and programatically a good decision.

technorati tags:, , , ,

Share/Save

Posted in Java, General | 6 Comments »

Select/delete all items in Solr

March 2nd, 2007 by Sebastian Mitroi

To select all items for a field in Solr you can use the query : some_item:[* TO *], but if this field is missing from some documents you will not select those documents.

To select all documents you can use the id defined in /conf/schema.xml, for example: <uniqueKey>solr_id</uniqueKey> you can use solr_id:[* TO *].

Now that you have all documents selected you can delete them :D

To delete all documents in Solr use this update xml:

<delete><query>solr_id:[*TO *]</query></delete>

and of course you have to commit:

<commit />

That’s all !



Share/Save

Posted in General | 2 Comments »

Chaining multiple view resolvers in Spring - using two InternalResourceViewResolver

March 1st, 2007 by Marius Hanganu

Spring allows chaining of multiple view resolvers . However, there are some view resolvers like the ones extending UrlBasedViewResolver which must be the last in the chain, hence the limitation of having only one such view resolver in your chain.
Javadoc for UrlBasedViewResolver mentions: “Note: When chaining ViewResolvers, a UrlBasedViewResolver always needs to be last, as it will attempt to resolve any view name, no matter whether the underlying resource actually exists.”

There are however situations in which one needs chaining multiple view resolvers such as InternalResourceViewResolver or UrlBasedViewResolver. For example, you need to support views returned both as JSP pages and Tiles layouts.

Chaining two InternalResourceViewResolver won’t do the job, since the first one will always try to resolve your view, and it will fail either on the JSP page or Tiles layout.

In order to support this feature you have to write your own view resolver extending UrlBasedViewResolver. Here’s an idea on how you can chain these resolvers: your custom view resolver can analyze the view returned by your Spring MVC controller and check its name. If it’s name contains the suffix “.layout”, your ViewResolver will pass control to the other view resolvers in the chain. Here’s a sample code:

/**
* Custom view resolver - checks if view name contains string layout, in which case lets the request
* reach the other view resolvers in the chain
*
* @author Marius Hanganu
*/
public class MyViewResolver extends UrlBasedViewResolver implements Ordered {
    /**
    * Overrides loadView in UrlBasedViewResolver to be able to make a     difference when letting the other views
    * in the chaing take control of the request
    *
    * @see org.springframework.web.servlet.view.UrlBasedViewResolver#loadView(String,java.util.Locale)
    */
    protected View loadView(String viewName, Locale locale) throws Exception {
    AbstractUrlBasedView view = buildView(viewName);
    View viewObj = (View)     getApplicationContext().getAutowireCapableBeanFactory().initializeBean(view, viewName);
        if (viewObj instanceof JstlView) {
            JstlView jv = (JstlView) viewObj;
            if (jv.getBeanName().indexOf(”layout”) != -1) {
                return null;
            }
        }

        return viewObj;
    }
}

The only other thing one needs to do is to declare the view resolvers.

<bean id=”viewResolver” class=”ro.tremend.bigg.web.spring.BiggViewResolver”>
    <property name=”order” value=”1″/>
    <property name=”viewClass” value=”org.springframework.web.servlet.view.JstlView”/>
    <property name=”prefix” value=”/WEB-INF/jsp/”/>
    <property name=”suffix” value=”.jsp”/>
</bean>

<bean id=”tilesViewResolver” class=”org.springframework.web.servlet.view.InternalResourceViewResolver”>
    <property name=”order” value=”2″/>
    <property name=”requestContextAttribute” value=”requestContext”/>
    <property name=”viewClass” value=”org.springframework.web.servlet.view.tiles.TilesJstlView”/>
</bean>

Share/Save

Posted in Java, General, Spring | 1 Comment »

AJAX file upload monitoring - monitor your file upload with DWR and commons-fileupload

March 1st, 2007 by Marius Hanganu

Monitoring your file upload using ajax is a must have for any web 2.0 application. There are already some good examples developed by prosson and carsonm.

The first one looks great, but it is VERY slow. Takes several minutes to upload a file of 40M on localhost on my Core Duo which is Unnaceptable.

Fortunately, the second has the right speed. Actually it has it all, being written with prototype. The version I’m posting on this entry is just a variation to the version posted on mission data blog, using DWR. You can download all sources and dependencies along with Intellij IDEA project here.

The mechanism is simple and works like this:

  1. upload request is made with a dummy target (an embedded invisible iframe)
  2. on the server side, the upload servlet starts monitoring the upload and sets some objects on the session
  3. on the client side, a request for checking progress is made shortly after the upload has been triggered
  4. using DWR this request goes to a DWR proxy on the server side which returns some statistics
  5. when the upload servlet finished the upload, it will signal this to the DWR proxy, so that the next request for progress will be the last one

To integrate this in your own application you must do the following:

1. In web.xml declare the upload servlet and the dwr servlet (if it’s not there already):

    <servlet>

        <servlet-name>UploadServlet</servlet-name>

        <servlet-class>ro.tremend.upload.UploadServlet</servlet-class>

    </servlet>



    <servlet>

        <servlet-name>dwr-invoker</servlet-name>

        <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>

        <init-param>

            <param-name>debug</param-name>

            <param-value>true</param-value>

        </init-param>

        <init-param>

            <param-name>scriptCompressed</param-name>

            <param-value>true</param-value>

        </init-param>

        <load-on-startup>2</load-on-startup>

    </servlet>



    <servlet-mapping>

        <servlet-name>UploadServlet</servlet-name>

        <url-pattern>/Upload</url-pattern>

    </servlet-mapping>



    <servlet-mapping>

        <servlet-name>dwr-invoker</servlet-name>

        <url-pattern>/dwr/*</url-pattern>

    </servlet-mapping>



2. In dwr.xml declare your proxy and a converter for the status object returned to UI:

    <create creator=”new” javascript=”uploadProxy”>

        <param name=”class” value=”ro.tremend.upload.UploadProxy”/>

    </create>



    <convert converter=”bean” match=”ro.tremend.upload.UploadStatus”/>



3. In your jsp or html page add the following:

    <iframe id=’target_upload’ name=’target_upload’ src=” style=’display: none’></iframe>



    <form enctype=”multipart/form-data” name=”form” method=”post” action=”Upload” onsubmit=”return startUploadMonitoring();” target=”target_upload”>

        File to upload: <input id=”importFile” name=”importFile” type=”file”> <br/>

        <input id=”submitButton” type=”submit” value=”Upload”/>

    </form>



    <div id=”uploadStatus”>

        <!– specify width on this uploadProgressBar, otherwise the progress indicator won’t move –>

        <div id=”uploadProgressBar” style=”width:200px;”>

            <div id=”uploadIndicator”></div>

        </div>

        <div id=”uploadPercentage”></div>

    </div>



The iframe is used to swallow the response to the upload request. The form contains the upload fields and the button. The uploadStatus div will hold the progress monitor.



4. In the head section of your jsp or html you will have to add the following:



    <style type=”text/css”>

        #uploadStatus {

            width: 230px;

        }



        #uploadProgressBar {

            height: 14px;

            border: 1px solid #BBB;

            text-align: center;

            display: inline;

            float: left;

        }



        #uploadIndicator {

            height: 10px;

            position: relative;

            margin: 1px;

            padding: 1px;

            background: #9DC0F4;

            width: 0;

            float: left;

        }



        #uploadPercentage {

            width: 20px;

            display: inline;

            float: right;

        }

    </style>



    <script type=’text/javascript’ src=”dwr/util.js”></script>

    <script type=’text/javascript’ src=”dwr/engine.js”></script>

    <script type=”text/javascript” src=”dwr/interface/uploadProxy.js”></script>



    <script type=”text/javascript” language=”JavaScript”>

        var updater = null;



        function checkStatus() {

            uploadProxy.getStatus(function(stat) {

                if (stat.status == 2) {

                    updateProgressBar(100);

                    return;

                }



                if (stat.status == 3) {

                    alert(”An error has occured! ” + stat.message);

                    return;

                }



                if (stat.status == 4) {

                    alert(”An error has occured! ” + stat.message);

                    return;

                }



                // do something with the percentage (nice loading bar, simply show the percentage, etc)

                updateProgressBar(stat.percentComplete);

                window.setTimeout(”checkStatus()”, 500);

            });

        }



        function updateProgressBar(percentage) {

            // make sure you set the width style property for uploadProgressBar, otherwise progress.style.width won’t work

            var progress = document.getElementById(”uploadProgressBar”);

            var indicator = document.getElementById(”uploadIndicator”);

            var maxWidth = parseIntWithPx(progress.style.width) - 4;

            var width = percentage * maxWidth / 100;

            indicator.style.width = width + “px”;

            var perc = document.getElementById(”uploadPercentage”);

            perc.innerHTML = percentage + “%”;

        }



        function parseIntWithPx(str) {

            var strArray = str.split(”p”);

            return parseInt(strArray[0]);

        }



        function startUploadMonitoring() {

            window.setTimeout(”checkStatus()”, 500);

            return true;

        }

</script>



5. You can assign unique identifiers to the set of files you’re uploading. The UploadServlet will make sure when upload finished to make

all files available on the HttpSession object under the key you’ve specified. To do that you’ll have to:

    a) add a new field inside the form:

        <input type=”hidden” name=”uniqueFileIdentifier” value=”1234″/>

    b) in your java code, you can retrieve the files uploaded like this:

        List filesUploaded = (List) session.getAttribute(UploadServlet.FILES_UPLOADED);



   
This will return a list of FileItem objects (for more information check the commons file upload documentation).


technorati tags:, , , , ,

Share/Save

Posted in HTML, Javascript, Java, General | 13 Comments »