Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with recursive datamodel and calculate field in datamodel (java.lang.NullPointerException) #891

Closed
silvinus opened this issue Aug 12, 2014 · 5 comments
Labels
bug
Milestone

Comments

@silvinus
Copy link

@silvinus silvinus commented Aug 12, 2014

Hi,

I have a problem with initialization of paths in generated classes Qxxx.
I have a complex model with recursive classes, and some paths in Qxxx classes are null. I don't know why !

I post my simplified datamodel :

Component is the base class of my datamodel. Here there is a multiple recursion for parent, children and a calculated field wich return a specific parent (the parent which is of type Container)

@Entity(name = Component.NAME)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Component implements Serializable {
    public static final String NAME = "Component";

    @Id
    protected String id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    private Component parent;

    @QueryType(PropertyType.ENTITY)
    @Transient
    public Container getContainer(){
        Component temp = this.parent;
        if(this.parent instanceof HibernateProxy){
            temp = (Component) ((HibernateProxy) this.parent)
                    .getHibernateLazyInitializer().getImplementation();
        }

        if(temp instanceof Container)
            return (Container)temp;
        else{
            if (!temp.isRoot()) {
                return temp.getParent().getContainer();
            } else {
                return null;
            }
        }
    }

    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Component> children;

    protected Component() {

    }

    protected Component(String id, Component parent) {
        this.id = id;
        this.parent = parent;
        this.children = new HashSet<Component>();
    }

    @Transient
    public boolean isRoot() {
        return (parent == null);
    }
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Set<Component> getChildren() {
        return children;
    }

    public void setChildren(Set<Component> children) {
        this.children = children;
    }

    public Component getParent() {
        return parent;
    }

    public void setParent(Component parent) {
        this.parent = parent;
    }
}

Content class :

@Entity(name = Content.NAME)
public class Content extends Component {

    public static final String NAME = "Content";

    @Column(name = "quantity")
    private long quantity;

    public Content() {
        super(null, null);
    }

    public Content(String id, Component parent) {
        super(id, parent);
        this.quantity = 0;
    }

    @Override
    public String toString() {
        return "Content [id=" + id + " qty=" + quantity + "]";
    }

    public long getQuantity() {
        return quantity;
    }

    public void setQuantity(long quantity) {
        this.quantity = quantity;
    }
}

Container class :

@Entity(name = Container.NAME)
public class Container extends Component {

    public static final String NAME = "Container";

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "packaging_id")
    private Packaging packaging;

    public Container() {
        super(null, null);
    }

    public Container(String id, Component parent) {
        super(id, parent);
        this.packaging = null;
    }

    public Packaging getPackaging() {
        return packaging;
    }

    public void setPackaging(Packaging packaging) {
        this.packaging = packaging;
    }
}

Packaging class (is the class wich is nul in path) :

@Entity(name = Packaging.NAME)
public class Packaging implements Serializable {

    public static final String NAME = "Packaging";

    @Id
    private String id;

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

    public Packaging() {

    }

    public Packaging(String id, String description) {
        this.id = id;
        this.description = description;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

And my test class

@RunWith(JUnit4.class)
public class QueryDSL {
    @Test
    public void test(){
        // Here packaging is null.... Why ?
        assertNotNull(QContent.content.container.packaging);
        assertNotNull(QContent.content.container.packaging.id);
    }
}

Thank's for your help.

@timowest
Copy link
Member

@timowest timowest commented Aug 12, 2014

Paths are only initialized up to two levels down http://www.querydsl.com/static/querydsl/3.4.2/reference/html/ch03s03.html#d0e2181

You need to configure the code generation to get deeper paths.

@silvinus
Copy link
Author

@silvinus silvinus commented Aug 18, 2014

I'm sorry but your answer doesn't work for me. I added queryInit annotation (with * in parameter) in the Transient method getContainer and the field packaging is alwais null at initialization time.
Can you explain me how I do configure entities ?

@timowest
Copy link
Member

@timowest timowest commented Aug 18, 2014

Yes, looks like there might be an issue on the Querydsl side after all. I will take a closer look.

@timowest timowest added this to the 3.4.3 milestone Aug 18, 2014
@timowest timowest added the bug label Aug 18, 2014
@silvinus
Copy link
Author

@silvinus silvinus commented Aug 19, 2014

Thank's for your fix. All works !

@timowest
Copy link
Member

@timowest timowest commented Aug 31, 2014

Released in 3.4.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

2 participants
You can’t perform that action at this time.