how to create a manytomany relationship between an entity and org.hibernate.usertype.UserType

StackOverflow https://stackoverflow.com/questions/11452405

  •  20-06-2021
  •  | 
  •  

Question

I have an entity like this:

 @Entity
    @Table(name = "PLATFORM")
    public class Platform{

        @Id
        @Column(name = "PLATFORM_ID")
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Integer platformId;

        @ManyToOne(fetch=FetchType.EAGER)
        @JoinColumn(name="PLATFORM_TYPE_ID")
        private PlatformType platformType;

        //must be manytomany but how?
        private List<MimeType> supportedMimeTypes;
        ...

And I have a MimeType class which is a org.hibernate.usertype.UserType indeed.

import java.sql.Types;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class MimeType extends EnumarationType{
    private static final long serialVersionUID = 1L;

    public static final MimeType XML = new MimeType(new Integer(0), "XML");
    public static final MimeType JSON = new MimeType(new Integer(1), "JSON");

    protected static ArrayList<MimeType> list = new ArrayList<MimeType>();

    static {
        SQL_TYPES = new int[] { Types.INTEGER };
        list.add(XML);
        list.add(JSON);
    }

    public MimeType(){      
    }

    public MimeType(Integer value, String label) {
        super(value, label);
    }

    public List<?> getList() {
        return list;
    }

    public static MimeType getById(int id) {
        Iterator<MimeType> it = list.iterator();
        while (it.hasNext()) {
            MimeType status = it.next();
            int statusId = Integer.parseInt(status.getValue());
            if (statusId == id)
                return status;
        }
        return null;
    }

    public static MimeType getByName(String name) {
        Iterator<MimeType> it = list.iterator();
        while (it.hasNext()) {
            MimeType status = it.next();
            String statusName = status.getLabel();
            if (statusName.equalsIgnoreCase(name))
                return status;
        }
        return null;
    }
}

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Iterator;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

public abstract class EnumarationTypeBase implements UserType, Serializable {

    protected static int[] SQL_TYPES = { Types.VARCHAR };

    protected String label;

    protected Object value;

    protected String resourceKey;

    public EnumarationTypeBase() {
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public abstract List<?> getList();

    private Object getValue() {
        return value;
    }

    public void setValue(Object value) {
        this.value = value;
    }

    public EnumarationTypeBase resolveFromValue(Object value) {
        List<?> list = getList();

        if (list == null)
            return null;

        EnumarationTypeBase result = null;
        for (Iterator<?> itr = list.iterator(); itr.hasNext();) {
            EnumarationTypeBase enm = (EnumarationTypeBase) itr.next();
            if (enm.getValue().toString().equals(value.toString())) {
                result = enm;
                break;
            }
        }

        return result;
    }

    public EnumarationTypeBase resolveFromLabel(Object label) {
        List<?> list = getList();

        if (list == null)
            return null;

        EnumarationTypeBase result = null;
        for (Iterator<?> itr = list.iterator(); itr.hasNext();) {
            EnumarationTypeBase enm = (EnumarationTypeBase) itr.next();
            if (enm.getLabel().equals(label.toString())) {
                result = enm;
                break;
            }
        }

        return result;
    }

    public String toString() {
        return getLabel();
    }

    public int[] sqlTypes() {
        return SQL_TYPES;
    }

    public Class<?> returnedClass() {
        return getClass();
    }

    public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException,
            SQLException {

        value = resultSet.getString(names[0]);

        return resultSet.wasNull() ? null : resolveFromValue(value);
    }

    public void nullSafeSet(PreparedStatement statement, Object value, int index) throws HibernateException,
            SQLException {
        EnumarationTypeBase enumType = (EnumarationTypeBase) value;
        if (value == null) {
            statement.setNull(index, sqlTypes()[0]);
        } else {
            statement.setString(index, enumType.getValue().toString());
        }
    }

    public boolean equals(Object x, Object y) {
        if (x == y)
            return true;
        if (null == x || null == y)
            return false;
        return x.equals(y);
    }

    public boolean equals(Object obj) {
        if (obj instanceof EnumarationTypeBase)
            return this.getValue().equals(((EnumarationTypeBase) obj).getValue());

        return super.equals(obj);
    }

    public Object assemble(Serializable cached, Object owner) throws HibernateException {
        return cached;
    }

    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable) value;
    }

    public Object replace(Object original, Object target, Object owner) throws HibernateException {
        return original;
    }

    public Object deepCopy(Object value) {
        return value;
    }

    public boolean isMutable() {
        return false;
    }

    public int hashCode(Object x) throws HibernateException {
        return x.hashCode();
    }

    public int hashCode() {
        return (new Integer(this.getValue().toString())).intValue();
    }

    public String getResourceKey() {
        if (resourceKey == null)
            resourceKey = resolveFromValue(this.value).resourceKey;
        return resourceKey;
    }

    public void setResourceKey(String resourceKey) {
        this.resourceKey = resourceKey;
    }
}

public abstract class EnumarationType extends EnumarationTypeBase {

    protected static int[] SQL_TYPES = { Types.VARCHAR };

    public EnumarationType() {
    }

    public EnumarationType(Integer value, String label) {
        this.value = value.toString();
        this.label = label;
    }

    public EnumarationType(String value, String label) {
        this.value = value.toString();
        this.label = label;
    }

    public EnumarationType(Integer value, String label, String resourceKey) {
        this.value = value.toString();
        this.label = label;
        this.resourceKey = resourceKey;
    }

    public String getValue() {
        return (String) value;
    }

    public BigDecimal getBigDecimalValue() {
        BigDecimal tValue = new BigDecimal(getValue());
        return tValue;
    }

    public void setValue(String value) {
        this.value = value;
    }

}

So how could i define a manytomany relationship between the entity Platform and non-entity usertype MimeType.

Please help.

Was it helpful?

Solution

I solved the problem. Here is the working code

...  

    @ElementCollection(targetClass = MimeType.class,fetch=FetchType.EAGER) 
    @CollectionTable(name = "PLATFORM_MIME_TYPE", joinColumns = @JoinColumn(name = "PLATFORM_ID"))
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "MIME_TYPE_ID", columnDefinition="integer")
    @Type(
            type = Constants.ENUMERATION_TYPE,
            parameters = {
                    @Parameter(
                        name  = "enumClass",                     
                        value = "com.ba.reme.model.enums.MimeType"),
                    @Parameter(
                        name  = "identifierMethod",
                        value = "toInt"),
                    @Parameter(
                        name  = "valueOfMethod",
                        value = "fromInt")
                    }
        )
    private Set<MimeType> supportedMimeTypes;


    ...

And the MimeType enum :

public enum MimeType {
    XML(1), 
    JSON(2),
    RSS(3);

    private int value;

    MimeType(int value) {
        this.value = value;
    }

    // the identifierMethod
    public int toInt() {
      return value;
    }

     // the valueOfMethod
     public  static MimeType fromInt(int value) {   
         switch(value) {
             case 2: return JSON;
             case 3: return RSS;
             default: return XML;
         }
    }

    public String toString() {
      switch(this) {
        case RSS: return "rss";
        case JSON: return "json";
        default: return "xml";
      }
    }

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top