We're updating the issue view to help you get more done. 

When proxying an entity having a private default constructor, the log message is not very clear about the problem

Description

Assuming we have 2 entities:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 @Entity(name = "Parent") public static class Parent { private Integer id; private String name; private Parent() { name = "Empty"; } public Parent(String s) { this.name = s; } @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.AUTO) public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } @Entity(name = "Child") public static class Child { private Integer id; private Parent parent; public Child() { this.parent = new Parent( "Name" ); } @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.AUTO) public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY) public Parent getParent() { return parent; } public void setParent(Parent parent) { this.parent = parent; } }

And we execute the following test case:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 Child child = new Child(); EntityManager entityManager = null; EntityTransaction txn = null; try { entityManager = createEntityManager(); txn = entityManager.getTransaction(); txn.begin(); entityManager.persist( child ); txn.commit(); entityManager.clear(); Integer childId = child.getId(); Child childReference = entityManager.getReference( Child.class, childId ); try { assertEquals( child.getParent().getName(), childReference.getParent().getName() ); } catch (Exception expected) { assertEquals( NoSuchMethodException.class, ExceptionUtil.rootCause( expected ).getClass() ); } } catch (Throwable e) { if ( txn != null && txn.isActive() ) { txn.rollback(); } throw e; } finally { if ( entityManager != null ) { entityManager.close(); } }

The current log message looks like this:

1 java.lang.NoSuchMethodException: org.hibernate.jpa.test.callbacks.PrivateConstructorTest$Parent$HibernateProxy$JqCA43Dt.<init>()

We should provide a more meaningful exception message to indicate that the default private constructor interferes with the Proxy mechanism, and the user should use the public, protected or package-private visibility
instead.

Environment

None

Status

Assignee

Vlad Mihalcea

Reporter

Vlad Mihalcea

Fix versions

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

5.3.6

Priority

Major