'Make Hibernate use a different List wrapper than PersistentBag

The Problem with PersistentBag is that it violates the Collections API equals() contract, which breaks unit test assertions via AssertJ's containsExactlyInAnyOrder(). Hibernate also has different wrapper implementations such as PersistentList, is there a way to force Hibernate (version 5.6.7) to use those instead of PersistentBag?

@Entity
data class AnalysisType(
    @Id
    name: String,

    @Column(name = "reference_type")
    @OneToMany(fetch = LAZY, cascade = [])
    val referenceTypes: List<ReferenceType>
)

@Entity
data class ReferenceType(
    @Id
    val id: Long,

    @Column
    val name: String
)


Solution 1:[1]

I think there's something wrong with the unit tests. Comparing two collections using an equals doesn't seem the right approach. In particular, when using unordered lists, elements might not always be in the same order.

You also need to make sure that you've implemented the correct hashcode/equals for the entities. In java, for ReferenceType, it should look like:

        @Override
        public boolean equals(Object o) {
            if ( this == o ) {
                return true;
            }
            if ( !( o instanceof ReferenceType ) ) {
                return false;
            }
            ReferenceType rt = (ReferenceType) o;
            return Objects.equals( name, rt.name );
        }

        @Override
        public int hashCode() {
            return Objects.hash( name );
        }

That said, if you want to have a PersistentList, the mapping needs to reflect an ordered list. You can achieve this using @OrderColumn:

@Entity(name = "Person")
public static class Person {

    @Id
    private Long id;

    @OneToMany(cascade = CascadeType.ALL)
    @OrderColumn
    private List<Phone> phones = new ArrayList<>();

    //Getters and setters are omitted for brevity

}

You can find more in the Hibernate ORM documentation in the section about collections of entities.

Solution 2:[2]

If you are using containsExactlyInAnyOrder from assertj the order of the elements does not matter. You can check for duplicates. If the PersistentBag contains the same element twice you should use containsOnly which does not care about the order and is ignoring duplicates. The equals method on the PersistentBag should not matter too because the contains... assertions in assertj are comparing element by element for the collections.

It looks like they may be sth wrong in your tests. Can you post assertj message?

Solution 3:[3]

From the keyboard documentation there are some ideas, if you want to continue using this library.

In particular, if you want to wait repeatedly on a key press, I would recommend the section in the documentation called: "Repeatedly waiting for a key press" which has the exact commands to run in order to achieve this. It also is very helpful because it gives you examples of what to do and what not to do when using the library.

For instance, I found the following basic example helpful:

import keyboard


keyboard.add_hotkey('space', lambda: print('space was pressed!'))

keyboard.wait('space')

After running this, the program will wait for your input. If you press space, the output:

space was pressed!

will be generated, and the program will terminate. Also, I needed to run the python file as an administrator (I put sudo in front of the command for this, not sure if this is recommended or secure).

I hope this helps guide you.

Edit: Using sudo on the command line. I use VS code, so I just press the "up" arrow on my command line to go to the most recent command, and then I type sudo in front. See the picture below:

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Qnzvna
Solution 3