1

Facing a strange issue while using @ManyToOne on non-primary keys of parent entities. When i fetch child entity hibernate is fetching parent entity too even though it is asked to fetch that lazily and I didn't query anything from parent entity.

Here is the example entity that I am using

Property Entity is the parent entity which has a column property_id and it is non-primary key.

public class Property extends AbstractEntity implements Serializable {

private static final long serialVersionUID = 8412320472079820864L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
Long id;

@Column(name = "property_id")
public Long propertyId;

@NotNull(message = "Name can't be null")
@Size(max = 100)
@Column(name = "name")
public String name;

Now I have a Room entity which is mapped with Property entity via column property_id.

public class Room extends AbstractEntity implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
Long id;

@Column(name = "name")
private String name;

@Column(name = "size")
private String size;

@Column(name = "room_type")
private RoomType roomType = RoomType.STANDARD_ROOM;

@ManyToOne(targetEntity = Property.class, fetch = FetchType.LAZY)
@JoinColumn(name = "property_id", referencedColumnName = "property_id", nullable = false)
private Property property;

@Column(name = "priority")
private Integer priority;

Now when I fetch Room hibernate hits database to fetch property too.

Can someone please explain what is it that I am missing?

I tried implementing interceptor still no luck

@ManyToOne(fetch = FetchType.LAZY,optional = false)
@JoinColumn(name = "property_id", referencedColumnName = "property_id", insertable = false, updatable = false)
@LazyToOne(LazyToOneOption.NO_PROXY)
public Property getProperty() {
    if (interceptor != null) {
        return (Property) interceptor.readObject(this, "property", property);
    }
    return property;
}

public void setProperty(Property property) {
    if (interceptor != null) {
        this.property = (Property)interceptor.writeObject(this, "property", this.property, property);
        return;
    }
    this.property = property;
}

P.s: I tried to use @NaturalId annotation too but it didn't worked.

  • Not sure if it has anything to do with the problem, but why do you have two keys? Why have both id and property_id in Property? – ewramner Mar 14 '19 at 07:06
  • actually we are migrating data from one service to other and we need to preserve that other system's database id so made this, and now this is becoming the bottleneck. – Ekansh Gautam Mar 14 '19 at 07:33
  • See this: https://stackoverflow.com/questions/30082281/manytoonefetch-fetchtype-lazy-doesnt-work-on-non-primary-key-referenced-co –  Mar 14 '19 at 07:50
  • still no luck, updated my question too – Ekansh Gautam Mar 14 '19 at 08:35
  • Well, how about migrating the other system's ids into your own id column and make sure that your generated ids start somewhere above them? A long is quite large, so reasonably there should be plenty of room left even if you take the largest used value and add a reasonable margin. Then you can have a clean data model without this exotic mapping. – ewramner Mar 14 '19 at 08:51

0 Answers0