Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate JPA OneToOne querying despite Lazy Fetch

Tags:

hibernate

I am having problems where Hibernate is querying a class on the other side of a lazy onetoone relationship.

The query to top_players, depending on the cache settings does a query through a mapping table to get the IDs for the QHPlayer table.

After doing the main query, it queries for each instance of the QHPlayer table.

However, it does the wrong thing in two different scenarios.

If I have caching turned on, it will query the instances of QHPlayer and then it will querying through to the inventory_item table. If I have caching turned off, it will make the query to QHPlayer with a join to inventory_item.

The problem is that no matter how I do it, it insists upon querying the inventory_item table. This is what I don't want. I don't need the data in inventory_item at this time.

I'm assuming something is wrong about my onetoone declarations between QHPlayer and PlayerInventoryItem.

Any ideas please?

The relevant code is below:

    Query query = entityManager.createQuery( "SELECT c FROM top_players c WHERE c.teamId=:teamId ORDER BY c.level DESC, c.adjustedFantasyPointsTotal DESC, c.id ASC" );
    query.setParameter( "teamId", teamId );
    List<TopPlayers> results = query.getResultList();



    @XmlAccessorType( XmlAccessType.PROPERTY)
@Entity( name="player_template")
@Table( name="player_template" )
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class QhPlayer implements Serializable {

    @Id
    public Integer getPlayerTemplateId() {
        return playerTemplateId;
    }

    @OneToOne( mappedBy ="playerTemplate", fetch = FetchType.LAZY)
    @XmlTransient
    public PlayerInventoryItem getInventoryItem() {
        return inventoryItem;
    }

}


@Entity( name = "qhplayer_inventory_item" )
@DiscriminatorValue("PLAYER")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class PlayerInventoryItem extends InventoryItem {
    private QhPlayer playerTemplate;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="player_template_id")
    @XmlTransient
    public QhPlayer getPlayerTemplate() {
        return playerTemplate;
    }
}



@Entity( name="inventory_item" )
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
        name = "inventory_item_type",
        discriminatorType = DiscriminatorType.STRING
)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public abstract class InventoryItem {
    private int inventoryItemId;
}



@Entity( name = "top_players")
@XmlRootElement(name = "top_player")
@Table(name="player")
@SecondaryTables({
        @SecondaryTable(name="player_stats", pkJoinColumns={
                @PrimaryKeyJoinColumn(name="playerId", referencedColumnName="id")
        }),
        @SecondaryTable(name="player_mapping", pkJoinColumns={
                @PrimaryKeyJoinColumn(name="playerId", referencedColumnName="id")
        })       
})
@XmlAccessorType( XmlAccessType.PROPERTY )
public class TopPlayers {

    private QhPlayer playerTemplate;

    @XmlTransient
    @ManyToOne
    @JoinColumn( table="player_mapping", name = "player_template_id", nullable = true )
    public QhPlayer getPlayerTemplate() {
        return playerTemplate;
    }
}
like image 852
Andrew Avatar asked Jan 11 '11 03:01

Andrew


1 Answers

I found the answer.

It is because the one-to-one is nullable. Then it cannot implement a lazy loading object. So I resolved it by going to a many-to-one relationship and just looking for the set of one object.

Here's a good reference.
http://community.jboss.org/wiki/Someexplanationsonlazyloadingone-to-one

Thanks in the meantime for anyone who read this.

like image 58
Andrew Avatar answered Oct 20 '22 17:10

Andrew