]> git.mxchange.org Git - jjobs-mailer-ejb.git/commitdiff
Continued with email delivery:
authorRoland Haeder <roland@mxchange.org>
Sun, 13 Mar 2016 17:31:20 +0000 (18:31 +0100)
committerRoland Haeder <roland@mxchange.org>
Sun, 13 Mar 2016 17:32:35 +0000 (18:32 +0100)
- Added EJB for email change mail delivery
- added needed jar(s)
- updated project files

lib/jmailer-ee.jar [new file with mode: 0644]
nbproject/build-impl.xml
nbproject/genfiles.properties
nbproject/project.properties
nbproject/project.xml
src/java/org/mxchange/jusercore/model/email_address/AddressbookEmailChangeSessionBean.java

diff --git a/lib/jmailer-ee.jar b/lib/jmailer-ee.jar
new file mode 100644 (file)
index 0000000..ec343a7
Binary files /dev/null and b/lib/jmailer-ee.jar differ
index 6a0a390c4bb4463939b93e00840464ca8c48a6f8..ba62e202a2be6649b2aa4a0b13f86539c28410f5 100644 (file)
@@ -841,6 +841,7 @@ exists or setup the property manually. For example like this:
         <copyfiles files="${file.reference.jcontacts-business-core.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${file.reference.juser-core.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${file.reference.juser-lib.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${file.reference.jcontacts-business-core.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${file.reference.juser-core.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${file.reference.juser-lib.jar}" todir="${build.classes.dir}"/>
+        <copyfiles files="${file.reference.jmailer-ee.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${reference.addressbook-lib.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${reference.juser-core.jar}" todir="${build.classes.dir}"/>
     </target>
         <copyfiles files="${reference.addressbook-lib.jar}" todir="${build.classes.dir}"/>
         <copyfiles files="${reference.juser-core.jar}" todir="${build.classes.dir}"/>
     </target>
@@ -854,10 +855,11 @@ exists or setup the property manually. For example like this:
         <basename file="${file.reference.jcontacts-business-core.jar}" property="manifest.file.reference.jcontacts-business-core.jar"/>
         <basename file="${file.reference.juser-core.jar}" property="manifest.file.reference.juser-core.jar"/>
         <basename file="${file.reference.juser-lib.jar}" property="manifest.file.reference.juser-lib.jar"/>
         <basename file="${file.reference.jcontacts-business-core.jar}" property="manifest.file.reference.jcontacts-business-core.jar"/>
         <basename file="${file.reference.juser-core.jar}" property="manifest.file.reference.juser-core.jar"/>
         <basename file="${file.reference.juser-lib.jar}" property="manifest.file.reference.juser-lib.jar"/>
+        <basename file="${file.reference.jmailer-ee.jar}" property="manifest.file.reference.jmailer-ee.jar"/>
         <basename file="${reference.addressbook-lib.jar}" property="manifest.reference.addressbook-lib.jar"/>
         <basename file="${reference.juser-core.jar}" property="manifest.reference.juser-core.jar"/>
         <manifest file="${build.ear.classes.dir}/META-INF/MANIFEST.MF" mode="update">
         <basename file="${reference.addressbook-lib.jar}" property="manifest.reference.addressbook-lib.jar"/>
         <basename file="${reference.juser-core.jar}" property="manifest.reference.juser-core.jar"/>
         <manifest file="${build.ear.classes.dir}/META-INF/MANIFEST.MF" mode="update">
-            <attribute name="Extension-List" value="jar-1 jar-2 jar-3 jar-4 jar-5 jar-6 jar-7 jar-8 jar-9 jar-10 jar-11 "/>
+            <attribute name="Extension-List" value="jar-1 jar-2 jar-3 jar-4 jar-5 jar-6 jar-7 jar-8 jar-9 jar-10 jar-11 jar-12 "/>
             <attribute name="jar-1-Extension-Name" value="${manifest.file.reference.jcore.jar}"/>
             <attribute name="jar-2-Extension-Name" value="${manifest.file.reference.jcoreee.jar}"/>
             <attribute name="jar-3-Extension-Name" value="${manifest.file.reference.jcore-logger-lib.jar}"/>
             <attribute name="jar-1-Extension-Name" value="${manifest.file.reference.jcore.jar}"/>
             <attribute name="jar-2-Extension-Name" value="${manifest.file.reference.jcoreee.jar}"/>
             <attribute name="jar-3-Extension-Name" value="${manifest.file.reference.jcore-logger-lib.jar}"/>
@@ -867,8 +869,9 @@ exists or setup the property manually. For example like this:
             <attribute name="jar-7-Extension-Name" value="${manifest.file.reference.jcontacts-business-core.jar}"/>
             <attribute name="jar-8-Extension-Name" value="${manifest.file.reference.juser-core.jar}"/>
             <attribute name="jar-9-Extension-Name" value="${manifest.file.reference.juser-lib.jar}"/>
             <attribute name="jar-7-Extension-Name" value="${manifest.file.reference.jcontacts-business-core.jar}"/>
             <attribute name="jar-8-Extension-Name" value="${manifest.file.reference.juser-core.jar}"/>
             <attribute name="jar-9-Extension-Name" value="${manifest.file.reference.juser-lib.jar}"/>
-            <attribute name="jar-10-Extension-Name" value="${manifest.reference.addressbook-lib.jar}"/>
-            <attribute name="jar-11-Extension-Name" value="${manifest.reference.juser-core.jar}"/>
+            <attribute name="jar-10-Extension-Name" value="${manifest.file.reference.jmailer-ee.jar}"/>
+            <attribute name="jar-11-Extension-Name" value="${manifest.reference.addressbook-lib.jar}"/>
+            <attribute name="jar-12-Extension-Name" value="${manifest.reference.juser-core.jar}"/>
         </manifest>
     </target>
     <target depends="compile" name="library-inclusion-in-manifest">
         </manifest>
     </target>
     <target depends="compile" name="library-inclusion-in-manifest">
@@ -881,6 +884,7 @@ exists or setup the property manually. For example like this:
         <copyfiles files="${file.reference.jcontacts-business-core.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.juser-core.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.juser-lib.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.jcontacts-business-core.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.juser-core.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${file.reference.juser-lib.jar}" todir="${dist.ear.dir}/lib"/>
+        <copyfiles files="${file.reference.jmailer-ee.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${reference.addressbook-lib.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${reference.juser-core.jar}" todir="${dist.ear.dir}/lib"/>
         <manifest file="${build.ear.classes.dir}/META-INF/MANIFEST.MF" mode="update"/>
         <copyfiles files="${reference.addressbook-lib.jar}" todir="${dist.ear.dir}/lib"/>
         <copyfiles files="${reference.juser-core.jar}" todir="${dist.ear.dir}/lib"/>
         <manifest file="${build.ear.classes.dir}/META-INF/MANIFEST.MF" mode="update"/>
index 4f6f54093e5a0ae91de29544ea58213c1139eb24..566ff5d387fb7509d1ea6dd1ff154c06d5dad43c 100644 (file)
@@ -3,6 +3,6 @@ build.xml.script.CRC32=7d41e0fd
 build.xml.stylesheet.CRC32=5910fda3@1.51.1
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
 build.xml.stylesheet.CRC32=5910fda3@1.51.1
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=578b807a
-nbproject/build-impl.xml.script.CRC32=34424534
+nbproject/build-impl.xml.data.CRC32=4a04b58e
+nbproject/build-impl.xml.script.CRC32=5b2dfdcd
 nbproject/build-impl.xml.stylesheet.CRC32=6096d939@1.55.1
 nbproject/build-impl.xml.stylesheet.CRC32=6096d939@1.55.1
index 2fb4f979b905e4dfe93c51e9e9173a7a70e5b7e4..de73a6c52e5523fd76f7df7ac73058156bc11449 100644 (file)
@@ -27,6 +27,7 @@ file.reference.jcore-logger-lib.jar=lib/jcore-logger-lib.jar
 file.reference.jcore.jar=lib/jcore.jar
 file.reference.jcoreee.jar=lib/jcoreee.jar
 file.reference.jcountry-core.jar=lib/jcountry-core.jar
 file.reference.jcore.jar=lib/jcore.jar
 file.reference.jcoreee.jar=lib/jcoreee.jar
 file.reference.jcountry-core.jar=lib/jcountry-core.jar
+file.reference.jmailer-ee.jar=lib/jmailer-ee.jar
 file.reference.jphone-core.jar=lib/jphone-core.jar
 file.reference.juser-core.jar=lib/juser-core.jar
 file.reference.juser-lib.jar=lib/juser-lib.jar
 file.reference.jphone-core.jar=lib/jphone-core.jar
 file.reference.juser-core.jar=lib/juser-core.jar
 file.reference.juser-lib.jar=lib/juser-lib.jar
@@ -54,6 +55,7 @@ javac.classpath=\
     ${file.reference.jcontacts-business-core.jar}:\
     ${file.reference.juser-core.jar}:\
     ${file.reference.juser-lib.jar}:\
     ${file.reference.jcontacts-business-core.jar}:\
     ${file.reference.juser-core.jar}:\
     ${file.reference.juser-lib.jar}:\
+    ${file.reference.jmailer-ee.jar}:\
     ${reference.addressbook-lib.jar}:\
     ${reference.juser-core.jar}
 javac.compilerargs=-Xlint:unchecked -Xlint:deprecation
     ${reference.addressbook-lib.jar}:\
     ${reference.juser-core.jar}
 javac.compilerargs=-Xlint:unchecked -Xlint:deprecation
@@ -101,6 +103,7 @@ source.reference.jcore-logger-lib.jar=../jcore-logger-lib/src/
 source.reference.jcore.jar=../jcore/src/
 source.reference.jcoreee.jar=../jcoreee/src/
 source.reference.jcountry-core.jar=../jcountry-core/src/
 source.reference.jcore.jar=../jcore/src/
 source.reference.jcoreee.jar=../jcoreee/src/
 source.reference.jcountry-core.jar=../jcountry-core/src/
+source.reference.jmailer-ee.jar=../jmailer-ee/src/
 source.reference.jphone-core.jar=../jphone-core/src/
 source.reference.juser-core.jar=../juser-core/src/
 source.reference.juser-lib.jar=../juser-lib/src/
 source.reference.jphone-core.jar=../jphone-core/src/
 source.reference.juser-core.jar=../juser-core/src/
 source.reference.juser-lib.jar=../juser-lib/src/
index 8d34321aa88445be18d624191876cc818fbcd0a8..098497ac9caa9937697fa602a50cd44df0280b4b 100644 (file)
@@ -14,6 +14,7 @@
             <included-library dirs="200">file.reference.jcontacts-business-core.jar</included-library>
             <included-library dirs="200">file.reference.juser-core.jar</included-library>
             <included-library dirs="200">file.reference.juser-lib.jar</included-library>
             <included-library dirs="200">file.reference.jcontacts-business-core.jar</included-library>
             <included-library dirs="200">file.reference.juser-core.jar</included-library>
             <included-library dirs="200">file.reference.juser-lib.jar</included-library>
+            <included-library dirs="200">file.reference.jmailer-ee.jar</included-library>
             <included-library dirs="200">reference.addressbook-lib.jar</included-library>
             <included-library dirs="200">reference.juser-core.jar</included-library>
             <source-roots>
             <included-library dirs="200">reference.addressbook-lib.jar</included-library>
             <included-library dirs="200">reference.juser-core.jar</included-library>
             <source-roots>
index df02c0d89fba4829b20f65b51fd17e1ac56e9448..88d2c6e22149007523ab2983f762089f0bf77fb6 100644 (file)
 package org.mxchange.jusercore.model.email_address;
 
 import java.text.MessageFormat;
 package org.mxchange.jusercore.model.email_address;
 
 import java.text.MessageFormat;
+import java.util.GregorianCalendar;
 import java.util.List;
 import java.util.List;
+import javax.annotation.PostConstruct;
 import javax.ejb.EJB;
 import javax.ejb.EJBException;
 import javax.ejb.Stateless;
 import javax.ejb.EJB;
 import javax.ejb.EJBException;
 import javax.ejb.Stateless;
+import javax.faces.FacesException;
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.MessageProducer;
+import javax.jms.ObjectMessage;
+import javax.jms.Queue;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.Session;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
 import javax.persistence.NoResultException;
 import javax.persistence.Query;
 import org.mxchange.jcoreee.database.BaseDatabaseBean;
 import javax.persistence.NoResultException;
 import javax.persistence.Query;
 import org.mxchange.jcoreee.database.BaseDatabaseBean;
+import org.mxchange.jmailee.model.delivery.DeliverableEmail;
+import org.mxchange.jmailee.model.delivery.Mailer;
 import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
 import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
+import org.mxchange.jusercore.model.user.UserUtils;
 
 /**
  * A session bean for changing email addresses
 
 /**
  * A session bean for changing email addresses
@@ -39,6 +55,31 @@ public class AddressbookEmailChangeSessionBean extends BaseDatabaseBean implemen
         */
        private static final long serialVersionUID = 182_698_165_971_548L;
 
         */
        private static final long serialVersionUID = 182_698_165_971_548L;
 
+       /**
+        * Connection
+        */
+       private Connection connection;
+
+       /**
+        * Object message
+        */
+       private ObjectMessage message;
+
+       /**
+        * Message producer
+        */
+       private MessageProducer messageProducer;
+
+       /**
+        * Mailer message queue
+        */
+       private Queue queue;
+
+       /**
+        * Session instance
+        */
+       private Session session;
+
        /**
         * User bean
         */
        /**
         * User bean
         */
@@ -58,7 +99,7 @@ public class AddressbookEmailChangeSessionBean extends BaseDatabaseBean implemen
                this.getLoggerBeanLocal().logTrace("allQueuedAddressesAsList: CALLED!"); //NOI18N
 
                // Get named query
                this.getLoggerBeanLocal().logTrace("allQueuedAddressesAsList: CALLED!"); //NOI18N
 
                // Get named query
-               Query query = this.getEntityManager().createNamedQuery("AllEmailAddressChanges", List.class);
+               Query query = this.getEntityManager().createNamedQuery("AllEmailAddressChanges", List.class); //NOI18N
 
                // Get all entries
                List<String> emailAddresses = query.getResultList();
 
                // Get all entries
                List<String> emailAddresses = query.getResultList();
@@ -71,23 +112,78 @@ public class AddressbookEmailChangeSessionBean extends BaseDatabaseBean implemen
        }
 
        @Override
        }
 
        @Override
-       public void enqueueEmailAddressForChange (final ChangeableEmailAddress emailAddress) {
+       public void enqueueEmailAddressForChange (final ChangeableEmailAddress emailChange) {
                // Trace message
                // Trace message
-               this.getLoggerBeanLocal().logTrace(MessageFormat.format("enqueueEmailAddressForChange: emailAddress={0} - CALLED!", emailAddress));
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("enqueueEmailAddressForChange: emailChange={0} - CALLED!", emailChange)); //NOI18N
 
 
-               // user should not be null
-               if (null == emailAddress) {
+               // Email address change should be valid
+               if (null == emailChange) {
                        // Abort here
                        // Abort here
-                       throw new NullPointerException("emailAddress is null"); //NOI18N
-               } else if (!this.userBean.ifUserExists(emailAddress.getEmailChangeUser())) {
+                       throw new NullPointerException("emailChange is null"); //NOI18N
+               } else if (emailChange.getEmailChangeUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("emailChange.emailChangeUser is null"); //NOI18N
+               } else if (emailChange.getEmailChangeUser().getUserId() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("emailChange.emailChangeUser.userId is null"); //NOI18N
+               } else if (emailChange.getEmailChangeUser().getUserId() < 1) {
+                       // Not valid id
+                       throw new IllegalArgumentException(MessageFormat.format("emailChange.emailChangeUser.userId={0} is invalid.", emailChange.getEmailChangeUser().getUserId())); //NOI18N
+               } else if (!this.userBean.ifUserExists(emailChange.getEmailChangeUser())) {
                        // User does not exist
                        // User does not exist
-                       throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailAddress.getEmailChangeId())); //NOI18N
-               } else if (this.isEmailAddressEnqueued(emailAddress.getEmailAddress())) {
+                       throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailChange.getEmailChangeId())); //NOI18N
+               } else if (emailChange.getEmailAddress().trim().isEmpty()) {
+                       // Email address is empty
+                       throw new IllegalArgumentException("emailChange.emaiLAddress is empty."); //NOI18N
+               } else if (this.isEmailAddressEnqueued(emailChange.getEmailAddress())) {
                        // Email address is already enqueued
                        // Email address is already enqueued
-                       throw new EJBException(MessageFormat.format("Email address {0} is already enqueued.", emailAddress.getEmailAddress()));
+                       throw new EJBException(MessageFormat.format("Email address {0} is already enqueued.", emailChange.getEmailAddress())); //NOI18N
                }
 
                }
 
-               throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+               // The email change is not (yet) there, add secure hash and "created" timestamp
+               emailChange.setEmailChangeCreated(new GregorianCalendar());
+               this.generateSecureHash(emailChange);
+
+               // Persist it
+               //this.getEntityManager().persist(emailChange);
+
+               // Get mailer instance
+               DeliverableEmail mailer = new Mailer();
+
+               // Send out email change
+               mailer.sendEmailChangeMail(this.messageProducer, this.message, emailChange);
+       }
+
+       /**
+        * Initialization of this bean
+        */
+       @PostConstruct
+       public void init () {
+               try {
+                       // Get initial context
+                       Context context = new InitialContext();
+
+                       // Get factory from JMS resource
+                       QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup("jms/addressbook-queue-factory"); //NOI18N
+
+                       // Lookup queue
+                       this.queue = (Queue) context.lookup("jms/addressbook-email-queue"); //NOI18N
+
+                       // Create connection
+                       this.connection = connectionFactory.createConnection();
+
+                       // Init session instance
+                       this.session = this.connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+                       // And message producer
+                       this.messageProducer = this.session.createProducer(this.queue);
+
+                       // Finally the message instance itself
+                       this.message = this.session.createObjectMessage();
+               } catch (final NamingException | JMSException e) {
+                       // Continued to throw
+                       throw new FacesException(e);
+               }
        }
 
        @Override
        }
 
        @Override
@@ -126,9 +222,9 @@ public class AddressbookEmailChangeSessionBean extends BaseDatabaseBean implemen
        @Override
        public void updateEmailAddress (final ChangeableEmailAddress emailAddress) {
                // Trace message
        @Override
        public void updateEmailAddress (final ChangeableEmailAddress emailAddress) {
                // Trace message
-               this.getLoggerBeanLocal().logTrace(MessageFormat.format("updateEmailAddress: emailAddress={0} - CALLED!", emailAddress));
+               this.getLoggerBeanLocal().logTrace(MessageFormat.format("updateEmailAddress: emailAddress={0} - CALLED!", emailAddress)); //NOI18N
 
 
-               // user should not be null
+               // Email address change should be valid
                if (null == emailAddress) {
                        // Abort here
                        throw new NullPointerException("emailAddress is null"); //NOI18N
                if (null == emailAddress) {
                        // Abort here
                        throw new NullPointerException("emailAddress is null"); //NOI18N
@@ -138,15 +234,69 @@ public class AddressbookEmailChangeSessionBean extends BaseDatabaseBean implemen
                } else if (emailAddress.getEmailChangeId() < 1) {
                        // Not valid
                        throw new IllegalArgumentException(MessageFormat.format("emailAddress.emailChangeId={0} is not valid.", emailAddress.getEmailChangeId())); //NOI18N
                } else if (emailAddress.getEmailChangeId() < 1) {
                        // Not valid
                        throw new IllegalArgumentException(MessageFormat.format("emailAddress.emailChangeId={0} is not valid.", emailAddress.getEmailChangeId())); //NOI18N
+               } else if (emailAddress.getEmailAddress().trim().isEmpty()) {
+                       // Email address is empty
+                       throw new IllegalArgumentException("emailAddress.emaiLAddress is empty."); //NOI18N
                } else if (!this.userBean.ifUserExists(emailAddress.getEmailChangeUser())) {
                        // User does not exist
                        throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailAddress.getEmailChangeId())); //NOI18N
                } else if (!this.isEmailAddressEnqueued(emailAddress.getEmailAddress())) {
                        // Email address is not enqueued
                } else if (!this.userBean.ifUserExists(emailAddress.getEmailChangeUser())) {
                        // User does not exist
                        throw new EJBException(MessageFormat.format("Email change with id {0} does not exist.", emailAddress.getEmailChangeId())); //NOI18N
                } else if (!this.isEmailAddressEnqueued(emailAddress.getEmailAddress())) {
                        // Email address is not enqueued
-                       throw new EJBException(MessageFormat.format("Email address {0} is not enqueued.", emailAddress.getEmailAddress()));
+                       throw new EJBException(MessageFormat.format("Email address {0} is not enqueued.", emailAddress.getEmailAddress())); //NOI18N
                }
 
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
 
                }
 
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
 
+       /**
+        * Generates a secure, unique hash for given email address change. This
+        * requires to check if the hash is really not there.
+        * <p>
+        * @param emailAddress Email address change
+        */
+       private void generateSecureHash (final ChangeableEmailAddress emailAddress) {
+               // Email address change should be valid
+               if (null == emailAddress) {
+                       // Abort here
+                       throw new NullPointerException("emailAddress is null"); //NOI18N
+               } else if (emailAddress.getEmailAddress().trim().isEmpty()) {
+                       // Email address is empty
+                       throw new IllegalArgumentException("emailAddress.emaiLAddress is empty."); //NOI18N
+               }
+
+               // Initialize loop with null
+               String hash = null;
+
+               // Default is not used
+               boolean isUsed = true;
+
+               // Search for free hash
+               while (isUsed) {
+                       // Generate hash, there is already in UserUtils a nice method that can be used for this purpose.
+                       hash = UserUtils.encryptPassword(String.format("%s:%s", emailAddress.getEmailAddress(), emailAddress.toString())); //NOI18N
+
+                       // The hash *may* be unique, better test it
+                       Query query = this.getEntityManager().createNamedQuery("SearchEmailChangeByHash", EmailAddressChange.class); //NOI18N
+
+                       // Set hash as parameter
+                       query.setParameter("hash", hash); //NOI18N
+
+                       // Try to get single result
+                       try {
+                               // Get single result
+                               ChangeableEmailAddress dummy = (ChangeableEmailAddress) query.getSingleResult();
+                       } catch (final NoResultException ex) {
+                               // Not found
+                               isUsed = false;
+                       }
+               }
+
+               // hash should not be null and set
+               assert (hash != null) : "hash is null"; //NOI18N
+               assert (!hash.isEmpty()) : "hash is empty"; //NOI18N
+
+               // Set it in email change
+               emailAddress.setEmailChangeHash(hash);
+       }
+
 }
 }