<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <base href="https://hibernate.atlassian.net" /> 
        <title>Message Title</title> 
    </head> 
    <body class="jira" style="color: #333; font-family: Arial, sans-serif; font-size: 14px; line-height: 1.429"> 
        <table id="background-table" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; background-color: #f5f5f5; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt"> 
            <!-- header here --> 
            <tr> 
                <td id="header-pattern-container" style="padding: 0px; border-collapse: collapse; padding: 10px 20px"> 
                    <table id="header-pattern" cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt"> 
                        <tr> 
                            <td id="header-avatar-image-container" valign="top" style="padding: 0px; border-collapse: collapse; vertical-align: top; width: 32px; padding-right: 8px"> <img id="header-avatar-image" class="image_fix" src="https://secure.gravatar.com/avatar/be64e870f6247e5845af98b4fe88167f?d=mm&amp;s=48" height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top" /> 
                            </td> 
                            <td id="header-text-container" valign="middle" style="padding: 0px; border-collapse: collapse; vertical-align: middle; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px"> <a class="user-hover" rel="candrews" id="email_candrews" href="https://hibernate.atlassian.net/secure/ViewProfile.jspa?name=candrews" style="color:#6c797f;; color: #3b73af; text-decoration: none">Craig</a> <strong>commented</strong> on <a href="https://hibernate.atlassian.net/browse/HHH-9954" style="color: #3b73af; text-decoration: none"><img src="cid:jira-generated-image-avatar-e74c5496-c743-4ec0-ae68-040a93ce59a3" height="16" width="16" border="0" align="absmiddle" alt="Bug" /> HHH-9954</a> 
                            </td> 
                        </tr> 
                    </table> 
                </td> 
            </tr> 
            <tr> 
                <td id="email-content-container" style="padding: 0px; border-collapse: collapse; padding: 0 20px"> 
                    <table id="email-content-table" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-spacing: 0; border-collapse: separate"> 
                        <tr> 
                            <!-- there needs to be content in the cell for it to render in some clients --> 
                            <td class="email-content-rounded-top mobile-expand" style="padding: 0px; border-collapse: collapse; color: #fff; padding: 0 15px 0 16px; height: 15px; background-color: #fff; border-left: 1px solid #ccc; border-top: 1px solid #ccc; border-right: 1px solid #ccc; border-bottom: 0; border-top-right-radius: 5px; border-top-left-radius: 5px; height: 10px; line-height: 10px; padding: 0 15px 0 16px; mso-line-height-rule: exactly">
                                &nbsp;
                            </td> 
                        </tr> 
                        <tr> 
                            <td class="email-content-main mobile-expand " style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 0 16px; background-color: #fff"> 
                                <table class="page-title-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt"> 
                                    <tr> 
                                        <td style="vertical-align: top;; padding: 0px; border-collapse: collapse; padding-right: 5px; font-size: 20px; line-height: 30px; mso-line-height-rule: exactly" class="page-title-pattern-header-container"> <span class="page-title-pattern-header" style="font-family: Arial, sans-serif; padding: 0; font-size: 20px; line-height: 30px; mso-text-raise: 2px; mso-line-height-rule: exactly; vertical-align: middle"> <a href="https://hibernate.atlassian.net/browse/HHH-9954" style="color: #3b73af; text-decoration: none">Re: Equality checking should consider arrays</a> </span> 
                                        </td> 
                                    </tr> 
                                </table> 
                            </td> 
                        </tr> 
                        <tr> 
                            <td id="text-paragraph-pattern-top" class="email-content-main mobile-expand  comment-top-pattern" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 0 16px; background-color: #fff; border-bottom: none; padding-bottom: 0"> 
                                <table class="text-paragraph-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 2px"> 
                                    <tr> 
                                        <td class="text-paragraph-pattern-container mobile-resize-text " style="padding: 0px; border-collapse: collapse; padding: 0 0 10px 0"> 
                                            <p style="margin: 10px 0 0 0">Consider this field definition:</p> 
                                            <div class="code panel" style="border-width: 1px;; border: 1px solid #ccc; background: #f5f5f5; font-size: 12px; line-height: 1.333; font-family: monospace; border: 1px solid #ccc; -moz-border-radius: 3px 3px 3px 3px; border-radius: 3px 3px 3px 3px; margin: 9px 0">
                                                <div class="codeContent panelContent" style="padding: 9px 12px"> 
                                                    <pre class="code-java" style="margin: 10px 0 0 0; max-height: 30em; overflow: auto; white-space: pre-wrap; word-wrap: normal">
@org.hibernate.annotations.Type(type = <span class="code-quote" style="color: #009100">&quot;JsonType&quot;</span>, parameters = {
                @Parameter(name = <span class="code-quote" style="color: #009100">&quot;sqlType&quot;</span>, value = <span class="code-quote" style="color: #009100">&quot;2005&quot;</span>),
                @Parameter(name = <span class="code-quote" style="color: #009100">&quot;classType&quot;</span>, value = <span class="code-quote" style="color: #009100">&quot;java.util.Map&lt;java.lang.<span class="code-object" style="color: #910091; color: #009100">Integer</span>,[Ljava.lang.<span class="code-object" style="color: #910091; color: #009100">String</span>;&gt;&quot;</span>) })
<span class="code-keyword" style="color: #000091">private</span> Map&lt;<span class="code-object" style="color: #910091">Integer</span>, <span class="code-object" style="color: #910091">String</span>[]&gt; componentData;
</pre> 
                                                </div>
                                            </div> 
                                            <p style="margin: 10px 0 0 0">JsonType is:</p> 
                                            <div class="code panel" style="border-width: 1px;; border: 1px solid #ccc; background: #f5f5f5; font-size: 12px; line-height: 1.333; font-family: monospace; border: 1px solid #ccc; -moz-border-radius: 3px 3px 3px 3px; border-radius: 3px 3px 3px 3px; margin: 9px 0">
                                                <div class="codeContent panelContent" style="padding: 9px 12px"> 
                                                    <pre class="code-java" style="margin: 10px 0 0 0; max-height: 30em; overflow: auto; white-space: pre-wrap; word-wrap: normal">
<span class="code-keyword" style="color: #000091">import</span> java.io.IOException;
<span class="code-keyword" style="color: #000091">import</span> java.io.Serializable;
<span class="code-keyword" style="color: #000091">import</span> java.sql.PreparedStatement;
<span class="code-keyword" style="color: #000091">import</span> java.sql.ResultSet;
<span class="code-keyword" style="color: #000091">import</span> java.sql.SQLException;
<span class="code-keyword" style="color: #000091">import</span> java.sql.Types;
<span class="code-keyword" style="color: #000091">import</span> java.util.Properties;

<span class="code-keyword" style="color: #000091">import</span> org.hibernate.HibernateException;
<span class="code-keyword" style="color: #000091">import</span> org.hibernate.engine.spi.SessionImplementor;
<span class="code-keyword" style="color: #000091">import</span> org.hibernate.internal.util.compare.EqualsHelper;
<span class="code-keyword" style="color: #000091">import</span> org.hibernate.usertype.ParameterizedType;
<span class="code-keyword" style="color: #000091">import</span> org.hibernate.usertype.UserType;
<span class="code-keyword" style="color: #000091">import</span> org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

<span class="code-keyword" style="color: #000091">import</span> com.fasterxml.jackson.core.JsonProcessingException;
<span class="code-keyword" style="color: #000091">import</span> com.fasterxml.jackson.databind.JavaType;
<span class="code-keyword" style="color: #000091">import</span> com.fasterxml.jackson.databind.ObjectMapper;
<span class="code-keyword" style="color: #000091">import</span> com.fasterxml.jackson.databind.type.TypeFactory;
<span class="code-keyword" style="color: #000091">import</span> com.google.common.base.Objects;

/**
 * Hibernate {@link UserType} implementation to handle JSON objects
 *
 * @see https
 *      :<span class="code-comment" style="color: #808080">//docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/usertype/
</span> *      UserType.html
 */
@SuppressWarnings(<span class="code-quote" style="color: #009100">&quot;serial&quot;</span>)
<span class="code-keyword" style="color: #000091">public</span> class JsonType <span class="code-keyword" style="color: #000091">implements</span> UserType, ParameterizedType, Serializable {

        <span class="code-keyword" style="color: #000091">private</span> <span class="code-keyword" style="color: #000091">static</span> <span class="code-keyword" style="color: #000091">final</span> ObjectMapper MAPPER = Jackson2ObjectMapperBuilder
                        .json().build();

        <span class="code-keyword" style="color: #000091">private</span> <span class="code-keyword" style="color: #000091">static</span> <span class="code-keyword" style="color: #000091">final</span> <span class="code-object" style="color: #910091">String</span> CLASS_TYPE = <span class="code-quote" style="color: #009100">&quot;classType&quot;</span>;
        <span class="code-keyword" style="color: #000091">private</span> <span class="code-keyword" style="color: #000091">static</span> <span class="code-keyword" style="color: #000091">final</span> <span class="code-object" style="color: #910091">String</span> TYPE = <span class="code-quote" style="color: #009100">&quot;type&quot;</span>;

        <span class="code-keyword" style="color: #000091">private</span> JavaType javaType;
        <span class="code-keyword" style="color: #000091">private</span> <span class="code-object" style="color: #910091">int</span> sqlType = Types.VARCHAR; <span class="code-comment" style="color: #808080">// before any guessing
</span>
        @Override
        <span class="code-keyword" style="color: #000091">public</span> void setParameterValues(Properties params) {
                <span class="code-object" style="color: #910091">String</span> classTypeName = params.getProperty(CLASS_TYPE);
                <span class="code-keyword" style="color: #000091">this</span>.javaType = TypeFactory.defaultInstance().constructFromCanonical(
                                classTypeName);
                <span class="code-object" style="color: #910091">String</span> type = params.getProperty(TYPE);
                <span class="code-keyword" style="color: #000091">if</span> (type != <span class="code-keyword" style="color: #000091">null</span>) {
                        <span class="code-keyword" style="color: #000091">this</span>.sqlType = <span class="code-object" style="color: #910091">Integer</span>.decode(type).intValue();
                }

        }

        @Override
        <span class="code-keyword" style="color: #000091">public</span> <span class="code-object" style="color: #910091">Object</span> assemble(Serializable cached, <span class="code-object" style="color: #910091">Object</span> owner)
                        <span class="code-keyword" style="color: #000091">throws</span> HibernateException {
                <span class="code-keyword" style="color: #000091">return</span> <span class="code-keyword" style="color: #000091">this</span>.deepCopy(cached);
        }

        @Override
        <span class="code-keyword" style="color: #000091">public</span> <span class="code-object" style="color: #910091">Object</span> deepCopy(<span class="code-object" style="color: #910091">Object</span> value) <span class="code-keyword" style="color: #000091">throws</span> HibernateException {
                <span class="code-object" style="color: #910091">Object</span> copy = <span class="code-keyword" style="color: #000091">null</span>;
                <span class="code-keyword" style="color: #000091">if</span> (value != <span class="code-keyword" style="color: #000091">null</span>) {

                        <span class="code-keyword" style="color: #000091">try</span> {
                                <span class="code-keyword" style="color: #000091">return</span> MAPPER.readValue(MAPPER.writerFor(javaType)
                                                .writeValueAsString(value), <span class="code-keyword" style="color: #000091">this</span>.javaType);
                        } <span class="code-keyword" style="color: #000091">catch</span> (IOException e) {
                                <span class="code-keyword" style="color: #000091">throw</span> <span class="code-keyword" style="color: #000091">new</span> HibernateException(<span class="code-quote" style="color: #009100">&quot;unable to deep copy object&quot;</span>, e);
                        }
                }
                <span class="code-keyword" style="color: #000091">return</span> copy;
        }

        @Override
        <span class="code-keyword" style="color: #000091">public</span> Serializable disassemble(<span class="code-object" style="color: #910091">Object</span> value) <span class="code-keyword" style="color: #000091">throws</span> HibernateException {
                <span class="code-keyword" style="color: #000091">try</span> {
                        <span class="code-keyword" style="color: #000091">return</span> MAPPER.writerFor(javaType).writeValueAsString(value);
                } <span class="code-keyword" style="color: #000091">catch</span> (JsonProcessingException e) {
                        <span class="code-keyword" style="color: #000091">throw</span> <span class="code-keyword" style="color: #000091">new</span> HibernateException(<span class="code-quote" style="color: #009100">&quot;unable to disassemble object&quot;</span>, e);
                }
        }

        @Override
        <span class="code-keyword" style="color: #000091">public</span> <span class="code-object" style="color: #910091">boolean</span> equals(<span class="code-object" style="color: #910091">Object</span> x, <span class="code-object" style="color: #910091">Object</span> y) <span class="code-keyword" style="color: #000091">throws</span> HibernateException {
                <span class="code-keyword" style="color: #000091">return</span> EqualsHelper.equals(x, y);
        }

        @Override
        <span class="code-keyword" style="color: #000091">public</span> <span class="code-object" style="color: #910091">int</span> hashCode(<span class="code-object" style="color: #910091">Object</span> x) <span class="code-keyword" style="color: #000091">throws</span> HibernateException {
                <span class="code-keyword" style="color: #000091">return</span> Objects.hashCode(x);
        }

        @Override
        <span class="code-keyword" style="color: #000091">public</span> <span class="code-object" style="color: #910091">boolean</span> isMutable() {
                <span class="code-keyword" style="color: #000091">return</span> <span class="code-keyword" style="color: #000091">true</span>;
        }

        @Override
        <span class="code-keyword" style="color: #000091">public</span> <span class="code-object" style="color: #910091">Object</span> nullSafeGet(ResultSet rs, <span class="code-object" style="color: #910091">String</span>[] names,
                        SessionImplementor session, <span class="code-object" style="color: #910091">Object</span> owner)
                        <span class="code-keyword" style="color: #000091">throws</span> HibernateException, SQLException {
                <span class="code-object" style="color: #910091">Object</span> obj;
                <span class="code-keyword" style="color: #000091">if</span> (<span class="code-keyword" style="color: #000091">this</span>.sqlType == Types.CLOB || <span class="code-keyword" style="color: #000091">this</span>.sqlType == Types.BLOB) {
                        <span class="code-object" style="color: #910091">byte</span>[] bytes = rs.getBytes(names[0]);
                        <span class="code-keyword" style="color: #000091">if</span> (rs.wasNull() || bytes == <span class="code-keyword" style="color: #000091">null</span>) {
                                obj = <span class="code-keyword" style="color: #000091">null</span>;
                        } <span class="code-keyword" style="color: #000091">else</span> {
                                <span class="code-keyword" style="color: #000091">try</span> {
                                        obj = MAPPER.readValue(bytes, <span class="code-keyword" style="color: #000091">this</span>.javaType);
                                } <span class="code-keyword" style="color: #000091">catch</span> (IOException e) {
                                        <span class="code-keyword" style="color: #000091">throw</span> <span class="code-keyword" style="color: #000091">new</span> HibernateException(
                                                        <span class="code-quote" style="color: #009100">&quot;unable to read object from result set&quot;</span>, e);
                                }
                        }
                } <span class="code-keyword" style="color: #000091">else</span> {
                        <span class="code-keyword" style="color: #000091">try</span> {
                                <span class="code-keyword" style="color: #000091">final</span> <span class="code-object" style="color: #910091">String</span> string = rs.getString(names[0]);
                                <span class="code-keyword" style="color: #000091">if</span> (rs.wasNull()) {
                                        obj = <span class="code-keyword" style="color: #000091">null</span>;
                                } <span class="code-keyword" style="color: #000091">else</span> {
                                        obj = MAPPER.readValue(string, <span class="code-keyword" style="color: #000091">this</span>.javaType);
                                }
                        } <span class="code-keyword" style="color: #000091">catch</span> (IOException e) {
                                <span class="code-keyword" style="color: #000091">throw</span> <span class="code-keyword" style="color: #000091">new</span> HibernateException(
                                                <span class="code-quote" style="color: #009100">&quot;unable to read object from result set&quot;</span>, e);
                        }
                }
                <span class="code-keyword" style="color: #000091">return</span> obj;
        }

        @Override
        <span class="code-keyword" style="color: #000091">public</span> void nullSafeSet(PreparedStatement st, <span class="code-object" style="color: #910091">Object</span> value, <span class="code-object" style="color: #910091">int</span> index,
                        SessionImplementor session) <span class="code-keyword" style="color: #000091">throws</span> HibernateException, SQLException {
                <span class="code-keyword" style="color: #000091">if</span> (value == <span class="code-keyword" style="color: #000091">null</span>) {
                        st.setNull(index, <span class="code-keyword" style="color: #000091">this</span>.sqlType);
                } <span class="code-keyword" style="color: #000091">else</span> {

                        <span class="code-keyword" style="color: #000091">if</span> (<span class="code-keyword" style="color: #000091">this</span>.sqlType == Types.CLOB || <span class="code-keyword" style="color: #000091">this</span>.sqlType == Types.BLOB) {
                                <span class="code-keyword" style="color: #000091">try</span> {
                                        st.setBytes(index, MAPPER.writeValueAsBytes(value));
                                } <span class="code-keyword" style="color: #000091">catch</span> (JsonProcessingException e) {
                                        <span class="code-keyword" style="color: #000091">throw</span> <span class="code-keyword" style="color: #000091">new</span> HibernateException(
                                                        <span class="code-quote" style="color: #009100">&quot;unable to set object to result set&quot;</span>, e);
                                }
                        } <span class="code-keyword" style="color: #000091">else</span> {
                                <span class="code-keyword" style="color: #000091">try</span> {
                                        st.setString(index, MAPPER.writerFor(javaType)
                                                        .writeValueAsString(value));
                                } <span class="code-keyword" style="color: #000091">catch</span> (JsonProcessingException e) {
                                        <span class="code-keyword" style="color: #000091">throw</span> <span class="code-keyword" style="color: #000091">new</span> HibernateException(
                                                        <span class="code-quote" style="color: #009100">&quot;unable to set object to result set&quot;</span>, e);
                                }
                        }
                }
        }

        @Override
        <span class="code-keyword" style="color: #000091">public</span> <span class="code-object" style="color: #910091">Object</span> replace(<span class="code-object" style="color: #910091">Object</span> original, <span class="code-object" style="color: #910091">Object</span> target, <span class="code-object" style="color: #910091">Object</span> owner)
                        <span class="code-keyword" style="color: #000091">throws</span> HibernateException {
                <span class="code-keyword" style="color: #000091">return</span> <span class="code-keyword" style="color: #000091">this</span>.deepCopy(original);
        }

        @Override
        <span class="code-keyword" style="color: #000091">public</span> <span class="code-object" style="color: #910091">Class</span>&lt;?&gt; returnedClass() {
                <span class="code-keyword" style="color: #000091">return</span> <span class="code-keyword" style="color: #000091">this</span>.javaType.getRawClass();
        }

        @Override
        <span class="code-keyword" style="color: #000091">public</span> <span class="code-object" style="color: #910091">int</span>[] sqlTypes() {
                <span class="code-keyword" style="color: #000091">return</span> <span class="code-keyword" style="color: #000091">new</span> <span class="code-object" style="color: #910091">int</span>[] { sqlType };
        }
}
</pre> 
                                                </div>
                                            </div> 
                                            <p style="margin: 10px 0 0 0">The problem is in the equals implementation - the custom type mapper doesn't know what the type is, so it uses EqualsHelper (which in my opinion, make sense). But, EqualsHelper doesn't behave as (at least I would have) expected regarding arrays. The result is that this field is always dirty because equals always returns false.</p> 
                                            <p style="margin: 10px 0 0 0">This issue would occur with any custom type mapper that uses arrays along with EqualsHelper. I also see that org.hibernate.type.AbstractType.isEqual(Object, Object), org.hibernate.type.NullableType.isEqual(Object, Object), and org.hibernate.type.descriptor.java.AbstractTypeDescriptor.areEqual(T, T) use EqualsHelper - those classes are likely extended by custom types, and those types probably aren't providing custom implementation of &quot;is/areEqual&quot; so the EqualsHelper implementation is probably causing problems in those cases and people may not even be realizing it.</p> 
                                            <p style="margin: 10px 0 0 0">Based on the related tickets, there are probably other ways that the current EqualsHelper.equals implementation causes unexpected behavior... but this issue is what lead me to report this ticket and provide the fix seen in the pull request.</p> 
                                        </td> 
                                    </tr> 
                                </table> 
                            </td> 
                        </tr> 
                        <tr> 
                            <td class="email-content-main mobile-expand " style="padding: 0px; border-collapse: collapse; border-left: 1px solid #ccc; border-right: 1px solid #ccc; border-top: 0; border-bottom: 0; padding: 0 15px 0 16px; background-color: #fff"> 
                                <table id="actions-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px"> 
                                    <tr> 
                                        <td id="actions-pattern-container" valign="middle" style="padding: 0px; border-collapse: collapse; padding: 10px 0 10px 24px; vertical-align: middle; padding-left: 0"> 
                                            <table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt"> 
                                                <tr> 
                                                    <td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0px; vertical-align: middle"> <a href="https://hibernate.atlassian.net/browse/HHH-9954#add-comment" target="_blank" title="Add Comment" style="color: #3b73af; text-decoration: none"> <img class="actions-pattern-action-icon-image" src="cid:jira-generated-image-static-comment-icon-5e74e62f-6409-4b46-bd6a-9e3325868cf6" alt="Add Comment" title="Add Comment" height="16" width="16" border="0" style="vertical-align: middle" /> </a> 
                                                    </td> 
                                                    <td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px"> <a href="https://hibernate.atlassian.net/browse/HHH-9954#add-comment" target="_blank" title="Add Comment" style="color: #3b73af; text-decoration: none">Add Comment</a> 
                                                    </td> 
                                                </tr> 
                                            </table> 
                                        </td> 
                                    </tr> 
                                </table> 
                            </td> 
                        </tr> 
                        <!-- there needs to be content in the cell for it to render in some clients --> 
                        <tr> 
                            <td class="email-content-rounded-bottom mobile-expand" style="padding: 0px; border-collapse: collapse; color: #fff; padding: 0 15px 0 16px; height: 5px; line-height: 5px; background-color: #fff; border-top: 0; border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; border-right: 1px solid #ccc; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; mso-line-height-rule: exactly">
                                &nbsp;
                            </td> 
                        </tr> 
                    </table> 
                </td> 
            </tr> 
            <tr> 
                <td id="footer-pattern" style="padding: 0px; border-collapse: collapse; padding: 12px 20px"> 
                    <table id="footer-pattern-container" cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt"> 
                        <tr> 
                            <td id="footer-pattern-text" class="mobile-resize-text" width="100%" style="padding: 0px; border-collapse: collapse; color: #999; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px">
                                 This message was sent by Atlassian JIRA <span id="footer-build-information">(v7.0.0-OD-02-259#70102-<span title="6147844ca4f0fe2eb2b7ae6af1e7bdb8d38cf75d" data-commit-id="6147844ca4f0fe2eb2b7ae6af1e7bdb8d38cf75d}">sha1:6147844</span>)</span> 
                            </td> 
                            <td id="footer-pattern-logo-desktop-container" valign="top" style="padding: 0px; border-collapse: collapse; padding-left: 20px; vertical-align: top"> 
                                <table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt"> 
                                    <tr> 
                                        <td id="footer-pattern-logo-desktop-padding" style="padding: 0px; border-collapse: collapse; padding-top: 3px"> <img id="footer-pattern-logo-desktop" src="cid:jira-generated-image-static-footer-desktop-logo-dc892d56-a18e-4254-a024-d664deee6167" alt="Atlassian logo" title="Atlassian logo" width="169" height="36" class="image_fix" /> 
                                        </td> 
                                    </tr> 
                                </table> 
                            </td> 
                        </tr> 
                    </table> 
                </td> 
            </tr> 
        </table>   
    </body>
</html>