0

We are working on an payment application based on spring-boot 2.5.6. The application is hosted on docker and launched on Java 14. We created an abstract class named GeneralEnum which is @Embeddable and contains two variables int type and String value. All enumeration classes extend this base class and define constants inside it.

This decision is made to customize enumeration used in whole layer of application. You can see one example in below:

@Embeddable
public class ShapeEnum extends GeneralEnum {
   public static final ShapeEnum CIRCLE = new ShapeEnum(0, 'Circle');
   public static final ShapeEnum RECTANGLE = new ShapeEnum(1, 'Rectangle');

   public ShapeEnum(int type, String value) {
       super(type, value);
   }
}

This class is used in entity layer as embedded variable as follow:

@Entity
public class Shape {
    @Embedded
    @AttributeOverride(name = "type", column = @Column(name = "shape_type"))
    private ShapeEnum shapeType;
}

The system worked perfectly, but something wrong happens and the value field of ShapeEnum.RECTANGLE changed to Circle and type is changed to 0 (!!!) and after that system would fail (dumping RAM shown the change of value). As I tracked, the problem is occurred after running GC and when the ShapeEnum is not used for a while.

Would anyone make an idea what happens and how tackle this problem? For now, restarting docker container causes the app will work properly.

Thanks in advance.

---------------

The dump for another class is (TicketStatus class) shown below. The highlighted part is changed without reason. The first and second constants' value and type are the same. I am sure that setValue and setType won't call in the source-code.

enter image description here

8
  • Why exactly are you not using enums but classes? Commented Mar 26, 2022 at 14:45
  • This is the design decision. You can save enum either ordinal or exact string in database and can't customize it to save int type like field into db. We have so many enumeration and cant use serializer and deserializer like approach. Commented Mar 26, 2022 at 14:48
  • 3
    "The system worked perfectly, but something wrong happens." That is the opposite of "worked perfectly". This whole design is just horrible, please forgive me for saying so. To introduce something like this and scattering it across your whole application, just because you had some issue with mapping it to the database, is the cancer, not the cure. Or let us call it a ticking time bomb. Sorry, I know my remarks are not solving your problem. But the hint someone else wrote about making your pseudo enum values immutable, should be a helpful starting point. Commented Mar 26, 2022 at 16:34
  • 2
    You can be sure it is deterministic. That it deviates from your expectation, does not make it non-deterministic. 😉 Commented Mar 26, 2022 at 16:37
  • 1
    Another immutability idea: Java 16 introduced records as a final feature. In 14 and 15 it was in preview status. When you upgrade, maybe you can use the terse, expressive syntax to model your immutable pseudo enums and use them in a less painful way. But actually, real enums would be better than re-inventing the wheel. With enums you can model objects with multiple properties and even methods. Commented Mar 26, 2022 at 16:46

1 Answer 1

1

OK, so first I will say what the problem is not.

This problem is not caused by the garbage collector. The GC doesn't change the values of variables. Not static variables, and not instance variables. So it is not the GC that is causing the type field of some ShapeEnum that denotes a rectangle (1) to change to a circle (0).


You say:

As I tracked, the problem is occurred after running GC and when the ShapeEnum is not used for a while.

That statement is not conclusive evidence. What you are actually (probably) saying is that you observed an object with type of 0 when it should have been 1 ... at some time after a GC run. You (probably) didn't observe the change actually happening, and you (probably) can't be sure that the value was correct immediately before the GC ran. In fact, you (probably) can't even be sure that the value was wrong immediately after the GC ran.

(If you do have clear evidence rather than supposition, please add it to the question.)


So what actually is causing this change?

At this stage we can only guess. My guess would be that:

  • some part of your application is calling the setValue method when it shouldn't, or

  • you have multiple objects that represent the "enums" for (say) rectangle.


It strikes me that your implementation of these ersatz enums is fragile. They should be (at least loosely) immutable. You probably alter the GeneralEnum class to remove the setters, and make the type and value fields final.

If the objects are immutable, you won't have to worry about something changing them. There would be other ways to get a ShapeEnum with type == 1 and value.equals("Circle"), but you wouldn't be able to break CIRCLE or RECTANGLE.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for response. We had a method named GeneralEnum of(int type) which get a type and return an object correspond to that type. That method works wrong too. I added a picture from dump when the problem arised.
1) The new evidence shows that one of your objects is in the wrong state. It doesn't say when it got into the wrong state, or what caused the state to change. It certainly is NOT evidence that the GC did it. 2) I can't comment on what the of method because I can't see its implementation. In fact, I can't really say anything definitive about what >is< causing this ... for the same reason. The only definitive I / we can say about the cause is that it is NOT the GC.
Thanks for your comment. I will put some log inside the setter and constructor to gather more information.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.