Changeset 4205

Show
Ignore:
Timestamp:
27/01/09 15:53:25 (2 years ago)
Author:
michael
Message:

Ensure that the entity manager is always closed after the response has been sent.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/build.properties

    r3978 r4205  
    11project.name=restlet-jpa 
    2 project.rev=0.5 
     2project.rev=0.6 
    33project.status=release 
  • trunk/ivy.xml

    r3981 r4205  
    1616  <dependencies> 
    1717    <!-- Restlet --> 
    18     <dependency org="org.restlet" name="org.restlet" rev="1.1-RC2" conf="default"/> 
    19     <dependency org="com.noelios.restlet" name="com.noelios.restlet.ext.simple" rev="1.1-RC2" conf="test->default"/> 
    20     <dependency org="com.noelios.restlet" name="com.noelios.restlet.ext.net" rev="1.1-RC2" conf="test->default"/> 
     18    <dependency org="org.restlet" name="org.restlet" rev="1.1.1" conf="default"/> 
     19    <dependency org="com.noelios.restlet" name="com.noelios.restlet.ext.simple" rev="1.1.1" conf="test->default"/> 
     20    <dependency org="com.noelios.restlet" name="com.noelios.restlet.ext.net" rev="1.1.1" conf="test->default"/> 
    2121    <!-- JSON --> 
    2222    <dependency org="com.sdicons.jsontools" name="jsontools-core" rev="1.5" conf="json->default"/> 
  • trunk/src/main/java/org/sarugo/restlet/jpa/PersistenceApplication.java

    r3989 r4205  
    5858    /** Clears the thread-local {@link EntityManager}. */ 
    5959    public void clearEntityManager() { 
     60        EntityManager em = entityManager.get(); 
     61        if (em != null && em.isOpen()) { 
     62            em.close(); 
     63        } 
    6064        entityManager.remove(); 
    6165    } 
  • trunk/src/main/java/org/sarugo/restlet/jpa/TransactionFilter.java

    r3978 r4205  
    11package org.sarugo.restlet.jpa; 
    22 
     3import java.io.IOException; 
     4import java.io.InputStream; 
     5import java.io.OutputStream; 
     6import java.io.Reader; 
     7import java.io.Writer; 
     8import java.nio.channels.ReadableByteChannel; 
     9import java.nio.channels.WritableByteChannel; 
     10import java.util.Date; 
     11import java.util.List; 
    312import java.util.logging.Level; 
    413 
     
    1019import org.restlet.Filter; 
    1120import org.restlet.Restlet; 
     21import org.restlet.data.CharacterSet; 
     22import org.restlet.data.Digest; 
     23import org.restlet.data.Encoding; 
     24import org.restlet.data.Language; 
     25import org.restlet.data.MediaType; 
     26import org.restlet.data.Range; 
     27import org.restlet.data.Reference; 
    1228import org.restlet.data.Request; 
    1329import org.restlet.data.Response; 
    1430import org.restlet.data.Status; 
     31import org.restlet.data.Tag; 
     32import org.restlet.resource.Representation; 
    1533 
    1634/** 
     
    2543public class TransactionFilter extends Filter { 
    2644 
    27         public TransactionFilter() { 
    28                 super(); 
    29         } 
    30  
    31         public TransactionFilter(Context context) { 
    32                 super(context); 
    33         } 
    34  
    35         public TransactionFilter(Context context, Restlet next) { 
    36                 super(context, next); 
    37         } 
    38  
    39         public TransactionFilter(EntityRouter router) { 
    40                 super(router.getContext(), router); 
    41         } 
    42  
    43         @Override 
    44         public int doHandle(Request request, Response response) { 
    45                 int result = CONTINUE; 
    46                 PersistenceApplication app = (PersistenceApplication) Application 
    47                                 .getCurrent(); 
    48                 EntityTransaction t = app.getEntityManager().getTransaction(); 
    49                 t.begin(); 
    50                 try { 
    51                         result = super.doHandle(request, response); 
    52                         if (t.isActive() && !t.getRollbackOnly()) { 
    53                                 app.getEntityManager().flush(); 
    54                                 t.commit(); 
    55                         } 
    56                 } catch (RuntimeException e) { 
    57                         getLogger().log(Level.SEVERE, 
    58                                         "Unhandled exception caught, rolling back transaction.", e); 
    59                         response.setStatus(Status.SERVER_ERROR_INTERNAL); 
    60                 } finally { 
    61                         if (t.isActive()) { 
    62                                 t.rollback(); 
    63                         } 
    64                         app.clearEntityManager(); 
    65                 } 
    66                 return result; 
    67         } 
     45    public static class AutoClosingRepresentation extends Representation { 
     46 
     47        private final Representation entity; 
     48 
     49        public AutoClosingRepresentation(Representation entity) { 
     50            this.entity = entity; 
     51        } 
     52 
     53        @Override 
     54        public ReadableByteChannel getChannel() throws IOException { 
     55            ((PersistenceApplication) Application.getCurrent()) 
     56                    .clearEntityManager(); 
     57            return entity.getChannel(); 
     58        } 
     59 
     60        @Override 
     61        public Reader getReader() throws IOException { 
     62            ((PersistenceApplication) Application.getCurrent()) 
     63                    .clearEntityManager(); 
     64            return entity.getReader(); 
     65        } 
     66 
     67        @Override 
     68        public InputStream getStream() throws IOException { 
     69            ((PersistenceApplication) Application.getCurrent()) 
     70                    .clearEntityManager(); 
     71            return entity.getStream(); 
     72        } 
     73 
     74        @Override 
     75        public void write(OutputStream stream) throws IOException { 
     76            entity.write(stream); 
     77            ((PersistenceApplication) Application.getCurrent()) 
     78                    .clearEntityManager(); 
     79        } 
     80 
     81        @Override 
     82        public void write(WritableByteChannel channel) throws IOException { 
     83            entity.write(channel); 
     84            ((PersistenceApplication) Application.getCurrent()) 
     85                    .clearEntityManager(); 
     86        } 
     87 
     88        @Override 
     89        public void write(Writer writer) throws IOException { 
     90            entity.write(writer); 
     91            ((PersistenceApplication) Application.getCurrent()) 
     92                    .clearEntityManager(); 
     93        } 
     94 
     95        public boolean checkDigest() { 
     96            return entity.checkDigest(); 
     97        } 
     98 
     99        public boolean checkDigest(String algorithm) { 
     100            return entity.checkDigest(algorithm); 
     101        } 
     102 
     103        public Digest computeDigest(String algorithm) { 
     104            return entity.computeDigest(algorithm); 
     105        } 
     106 
     107        public boolean equals(Object obj) { 
     108            return entity.equals(obj); 
     109        } 
     110 
     111        public long exhaust() throws IOException { 
     112            return entity.exhaust(); 
     113        } 
     114 
     115        public long getAvailableSize() { 
     116            return entity.getAvailableSize(); 
     117        } 
     118 
     119        public CharacterSet getCharacterSet() { 
     120            return entity.getCharacterSet(); 
     121        } 
     122 
     123        public Digest getDigest() { 
     124            return entity.getDigest(); 
     125        } 
     126 
     127        public String getDownloadName() { 
     128            return entity.getDownloadName(); 
     129        } 
     130 
     131        public List<Encoding> getEncodings() { 
     132            return entity.getEncodings(); 
     133        } 
     134 
     135        public Date getExpirationDate() { 
     136            return entity.getExpirationDate(); 
     137        } 
     138 
     139        public Reference getIdentifier() { 
     140            return entity.getIdentifier(); 
     141        } 
     142 
     143        public List<Language> getLanguages() { 
     144            return entity.getLanguages(); 
     145        } 
     146 
     147        public MediaType getMediaType() { 
     148            return entity.getMediaType(); 
     149        } 
     150 
     151        public Date getModificationDate() { 
     152            return entity.getModificationDate(); 
     153        } 
     154 
     155        public Range getRange() { 
     156            return entity.getRange(); 
     157        } 
     158 
     159        public long getSize() { 
     160            return entity.getSize(); 
     161        } 
     162 
     163        public Tag getTag() { 
     164            return entity.getTag(); 
     165        } 
     166 
     167        public String getText() throws IOException { 
     168            return entity.getText(); 
     169        } 
     170 
     171        public int hashCode() { 
     172            return entity.hashCode(); 
     173        } 
     174 
     175        public boolean isAvailable() { 
     176            return entity.isAvailable(); 
     177        } 
     178 
     179        public boolean isDownloadable() { 
     180            return entity.isDownloadable(); 
     181        } 
     182 
     183        public boolean isTransient() { 
     184            return entity.isTransient(); 
     185        } 
     186 
     187        public void release() { 
     188            entity.release(); 
     189        } 
     190 
     191        public void setAvailable(boolean available) { 
     192            entity.setAvailable(available); 
     193        } 
     194 
     195        public void setCharacterSet(CharacterSet characterSet) { 
     196            entity.setCharacterSet(characterSet); 
     197        } 
     198 
     199        public void setDigest(Digest digest) { 
     200            entity.setDigest(digest); 
     201        } 
     202 
     203        public void setDownloadable(boolean downloadable) { 
     204            entity.setDownloadable(downloadable); 
     205        } 
     206 
     207        public void setDownloadName(String fileName) { 
     208            entity.setDownloadName(fileName); 
     209        } 
     210 
     211        public void setEncodings(List<Encoding> encodings) { 
     212            entity.setEncodings(encodings); 
     213        } 
     214 
     215        public void setExpirationDate(Date expirationDate) { 
     216            entity.setExpirationDate(expirationDate); 
     217        } 
     218 
     219        public void setIdentifier(Reference identifier) { 
     220            entity.setIdentifier(identifier); 
     221        } 
     222 
     223        public void setIdentifier(String identifierUri) { 
     224            entity.setIdentifier(identifierUri); 
     225        } 
     226 
     227        public void setLanguages(List<Language> languages) { 
     228            entity.setLanguages(languages); 
     229        } 
     230 
     231        public void setMediaType(MediaType mediaType) { 
     232            entity.setMediaType(mediaType); 
     233        } 
     234 
     235        public void setModificationDate(Date modificationDate) { 
     236            entity.setModificationDate(modificationDate); 
     237        } 
     238 
     239        public void setRange(Range range) { 
     240            entity.setRange(range); 
     241        } 
     242 
     243        public void setSize(long expectedSize) { 
     244            entity.setSize(expectedSize); 
     245        } 
     246 
     247        public void setTag(Tag tag) { 
     248            entity.setTag(tag); 
     249        } 
     250 
     251        public void setTransient(boolean isTransient) { 
     252            entity.setTransient(isTransient); 
     253        } 
     254 
     255        public String toString() { 
     256            return entity.toString(); 
     257        } 
     258 
     259    } 
     260 
     261    public TransactionFilter() { 
     262        super(); 
     263    } 
     264 
     265    public TransactionFilter(Context context) { 
     266        super(context); 
     267    } 
     268 
     269    public TransactionFilter(Context context, Restlet next) { 
     270        super(context, next); 
     271    } 
     272 
     273    public TransactionFilter(EntityRouter router) { 
     274        super(router.getContext(), router); 
     275    } 
     276 
     277    @Override 
     278    public int doHandle(Request request, Response response) { 
     279        int result = CONTINUE; 
     280        PersistenceApplication app = (PersistenceApplication) Application 
     281                .getCurrent(); 
     282        EntityTransaction t = app.getEntityManager().getTransaction(); 
     283        t.begin(); 
     284        try { 
     285            result = super.doHandle(request, response); 
     286            if (t.isActive() && !t.getRollbackOnly()) { 
     287                app.getEntityManager().flush(); 
     288                t.commit(); 
     289            } 
     290        } catch (RuntimeException e) { 
     291            getLogger().log(Level.SEVERE, 
     292                    "Unhandled exception caught, rolling back transaction.", e); 
     293            response.setStatus(Status.SERVER_ERROR_INTERNAL); 
     294        } finally { 
     295            if (t.isActive()) { 
     296                t.rollback(); 
     297            } 
     298            Representation entity = response.getEntity(); 
     299            if (entity != null) { 
     300                response.setEntity(new AutoClosingRepresentation(entity)); 
     301            } else { 
     302                app.clearEntityManager(); 
     303            } 
     304        } 
     305        return result; 
     306    } 
    68307 
    69308} 
  • trunk/src/main/java/org/sarugo/restlet/jpa/converter/Converter.java

    r3989 r4205  
    44import java.beans.PropertyEditorManager; 
    55import java.lang.reflect.Constructor; 
    6 import java.text.DateFormat; 
    7 import java.text.ParseException; 
    8 import java.text.SimpleDateFormat; 
    9 import java.util.Date; 
    106 
    117import org.sarugo.restlet.jpa.PersistenceApplication; 
     
    5854                } 
    5955 
    60                 // Otherwise, check for date 
    61                 if (type.isAssignableFrom(Date.class)) { 
    62                         try { 
    63                                 return type.cast(new SimpleDateFormat("dd/MM/yyyy") 
    64                                                 .parse(value)); 
    65                         } catch (ParseException e) { 
    66                                 // Ignore 
    67                         } 
    68                 } 
    69  
    7056                // Otherwise, use JavaBean coercion 
    7157                try {