Just another site

Category Archives: Java

Endless loop with ListIterator .hasNext()

The following code will create an endless loop because java creates new iterator everytime you call list.iterator():


We should do it this way:

Iterator iterator = someList.iterator();

POI read cell value as string

When you get error for reading cell value as string:

Cannot get a numeric value from a text cell
or Cannot get a boolean value from a text cell

The code below will format the cell properly and return string value:

final DataFormatter df = new DataFormatter();
final XSSFCell cell = row.getCell(cellIndex);
String valueAsString = df.formatCellValue(cell);

Create copy of a list

Sometimes we want to pass a list as parameter to a method, we will do some work on the list but don’t want to affect the origin list.

The code below is not good, as we are passing the orginal reference to the method, all changes will affect the orginal list


Instead, we should do something like:

     DoSomeWork(new ArrayList(SelectedPerson.getAllAddresses()));

Pleaes be awared that the second example passed a copy of the list to DoSomeWork, but the elements in the copy still hold reference to the orginal elements. Modifying any object element in the copy list will also change the element in the original.

JMS queue listener

Let’s say we are saving a note along some pics into the database. We will need to resize the pics and only save thumbnails. The resizing images part could take a couple seconds and we don’t want user to wait on the page, so we do it asynchronously.

The workflow would be: 1 save note;  2 flush session; 3 send resizing images request to jms ; 4 JMS queue listener receive the msg and find service action to create thumbnail.

During the resizing image process, I need to link the resized images to the note and then save the thumbnail. I had some code like below:

    public void createThumbnail(Note note){
        Note note = em.merge(note);

This doesn’t work because the process is asynchronous, when the resizing starts in JMS the note may not be in the database yet. What I had in my case the createThumbnail method then create another record for note, so I have duplicate record in the database.

To solve this problem, we should use find to look up the record in database before perform any action. If we can’t find the record in database then we should rollback and retry in JMS.

so the code goes:

    public void createThumbnail(Note note){
        Note newNote = em.find(note);
        if(newNote == null){

Read photo taken date from image

For Java, I use metadata-extractor:

Metadata metadata = ImageMetadataReader.readMetadata( item.getInputStream());
ExifSubIFDDirectory directory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
Date date = directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);
if(date != null){

For front end, I use exif-js:

window.resolveLocalFileSystemURL(attachmentInfo.fileSource, (fileEntry) ->
                fileEntry.file((file) ->
                    EXIF.getData(file, ->
                        galleryPhotoTakenDate = EXIF.getTag(this,"DateTimeOriginal");
                        cameraPhotoTakenDate = this.lastModifiedDate;

                        if photoFromCamera
                            if typeof cameraPhotoTakenDate != 'undefined'
                                #photo taken from camera
                                attachmentInfo.photoTakenDate = moment(cameraPhotoTakenDate).format("YYYY:MM:DD HH:mm:SS")
                            if typeof galleryPhotoTakenDate != 'undefined'
                                #photo taken from gallery
                                attachmentInfo.photoTakenDate = galleryPhotoTakenDate 

Zip4J bad crc error

I’m using Zip4J to compress images. The compression went properly but when I try to extract the images,  winrar gives me bad crc error. The problem is solved by changing the compression method to “store”:


Conditional operator in concatenated string

"Hazard Class changed from '" + hazardChangeTracker.getHealthSafetyClass()!=null?hazardChangeTracker.getHealthSafetyClass().getLabel():"Not Set"

The above code throws PNE because conditional operator has lower precedence level than addition operator. To make the code work, we need to add parentheses.

"Hazard Class changed from '" + (hazardChangeTracker.getHealthSafetyClass()!=null?hazardChangeTracker.getHealthSafetyClass().getLabel():"Not Set")

JsonMappingException: No suitable constructor found for type

You need a no-argument constructor for your entity

find object can’t be serialized

I encountered a problem today :one of the object can't be serialized, then I found
this useful code on from
       public static final Object clone(Serializable in) {
            try {
                ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
                ObjectOutputStream outStream = new ObjectOutputStream(byteOutStream);
                ByteArrayInputStream byteInStream =
                    new ByteArrayInputStream(byteOutStream.toByteArray());
                ObjectInputStream inStream = new ObjectInputStream(byteInStream);
                return inStream.readObject();
            } catch (OptionalDataException e) {
             throw new RuntimeException("Optional data found. " + e.getMessage()); 
            } catch (StreamCorruptedException e) {
             throw new RuntimeException("Serialized object got corrupted. " + e.getMessage());
            } catch (ClassNotFoundException e) {
             throw new RuntimeException("A class could not be found during deserialization. " + e.getMessage()); 
            } catch (NotSerializableException ex) {
             throw new IllegalArgumentException("Object is not serializable: " + ex.getMessage());
            } catch (IOException e) {
             throw new RuntimeException("IO operation failed during serialization. " + e.getMessage()); 

Hibernate one to many filtering

Recently I need to do an hiberate one to many filtering, but it’s not as easy as I thought.

Firstly, hibernate criteria doesn’t allow you join the same association twice, which mean you can’t have code like this:

finalCriteria.createAlias("a.b","b1", JoinType.LEFT_OUTER_JOIN)

.createAlias("a.b","b2", JoinType.LEFT_OUTER_JOIN);

Two workarounds are mentioned on, I tried use detachedCriteria but got the same error.

The second solution works for me:

Criterion  criterion  = Restrictions.sqlRestriction(" ((exists (select tc.OBJECT_ID from OP_TICKET_CATEGORY_OPERATOR tc where tc.TICKET_CATEGORY_ID = this_.OBJECT_ID AND tc.OPERATOR_ID ="+selectedResolver.getObjID()+" AND tc.OPERATOR_TYPE='RE')) AND (exists (select tc.OBJECT_ID from OP_TICKET_CATEGORY_OPERATOR tc where tc.TICKET_CATEGORY_ID = this_.OBJECT_ID AND tc.OPERATOR_ID ="+selectedOpener.getObjID()+" AND tc.OPERATOR_TYPE='OP')))" );




private List<TicketCategoryOperator> ticketCategoryOperators;



@JoinColumn(name = "TICKET_CATEGORY_ID",nullable = true)
private TicketCategory ticketCategory;

@JoinColumn(name = "OPERATOR_ID",nullable = true)
private Operator operator;

TicketCategoryOperatorType type = TicketCategoryOperatorType.OPENER;