Uploaded image for project: 'Beam'
  1. Beam
  2. BEAM-8364

SchemaCoder inconsistent equality behavior for POJO

Details

    • Bug
    • Status: Open
    • P3
    • Resolution: Unresolved
    • 2.16.0
    • None
    • dsl-sql, sdk-java-core

    Description

      One can create a SchemaCoder for arbitrary type T with SchemaCoder.of(schema, toRowFunction, fromRowFunction). However, in cases where T lacks proper equality behavior, i.e. POJO, the result coder still returns true for consistentWithEquals and {{structuralValue}}s that fail equality check.

      This test reproduces the issue.

      import org.apache.beam.sdk.schemas.Schema;
      import org.apache.beam.sdk.schemas.SchemaCoder;
      import org.apache.beam.sdk.values.Row;
      import org.junit.Test;
      import org.junit.runner.RunWith;
      import org.junit.runners.JUnit4;
      
      import java.nio.charset.Charset;
      
      import static org.junit.Assert.*;
      
      @RunWith(JUnit4.class)
      public class SchemaCoderTest {
      
        public static class Pojo {
          private final byte[] bytes;
          private final String id;
      
          public Pojo(byte[] bytes, String id) {
            this.bytes = bytes;
            this.id = id;
          }
      
          public byte[] getBytes() {
            return bytes;
          }
      
          public String getId() {
            return id;
          }
        }
      
        @Test
        public void testCoder() {
          Schema schema = Schema.builder().addByteArrayField("bytes").addStringField("id").build();
      
          SchemaCoder<Pojo> coder = SchemaCoder.<Pojo>of(
                  schema,
                  t -> Row.withSchema(schema).addValues(t.getBytes(), t.getId()).build(),
                  r -> new Pojo(r.getBytes("bytes"), r.getString("id")));
      
          Pojo p1 = new Pojo("hello".getBytes(Charset.forName("UTF-8")), "world");
          Pojo p2 = new Pojo("hello".getBytes(Charset.forName("UTF-8")), "world");
      
          assertNotEquals(p1, p2); // EXPECTED, p1.equals(p2) == false
      
          assertFalse(coder.consistentWithEquals()); // FAIL, returns true
          assertEquals(coder.structuralValue(p1), coder.structuralValue(p2)); // FAIL
        }
      }
      

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              sinisa_lyh Neville Li
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 1h
                  1h