package org.col.db.type;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Base class for type handlers that need to convert between columns of type
 * integer[] and fields of type Set&lt;Enum&gt;.
 *
 * @param <T>
 */
public abstract class EnumOrdinalSetTypeHandler<T extends Enum<T>> extends BaseTypeHandler<Set<T>> {

  private final T[] values;

  public EnumOrdinalSetTypeHandler(Class<T> enumClass) {
    values = enumClass.getEnumConstants();
  }

  @Override
	public void setNonNullParameter(PreparedStatement ps, int i, Set<T> parameter, JdbcType jdbcType) throws SQLException {
		Integer[] ordinals = new Integer[parameter.size()];
		int j = 0;
		for (T t : parameter) {
			ordinals[j++] = t.ordinal();
		}
		Array array = ps.getConnection().createArrayOf("int", ordinals);
		ps.setArray(i, array);
	}

	@Override
	public Set<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
		return convert(rs.getArray(columnName));
	}

	@Override
	public Set<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		return convert(rs.getArray(columnIndex));
	}

	@Override
	public Set<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		return convert(cs.getArray(columnIndex));
	}

	private Set<T> convert(Array pgArray) throws SQLException {
		if (pgArray == null) {
			return Collections.<T>emptySet();
		}
    return EnumSet.copyOf(Arrays.stream(((Integer[]) pgArray.getArray()))
        .map(i -> values[i])
        .collect(Collectors.toSet()));
  }

}

@@ -463,16 +463,52 @@
  values;
+%0A  private final Class%3CT%3E enumClass;
 %0A%0A  publ
@@ -558,16 +558,48 @@
 lass) %7B%0A
+    this.enumClass = enumClass;%0A
     valu
@@ -1526,46 +1526,121 @@
 null
-) %7B%0A%09%09%09return Collections.%3CT%3EemptySet(
+ %7C%7C pgArray.getArray() == null %7C%7C ((Integer%5B%5D)pgArray.getArray()).length==0) %7B%0A%09%09%09return EnumSet.noneOf(enumClass
 );%0A%09

Handle null issues columns in type handler safely