2

所以我要做的是创建一个 CriteriaQuery 并为地图的键添加一个位置,但我得到一个 NullPointerException。

SQL中的类似以下内容(只是为了更好地解释我的意思):

select test.* from test join test_translation on test_translation.id=test.id where test_translation.key='pt'

我成功地进行了 HQL 查询并使用了 index(),但我需要比这更动态的东西。这是有效的:

TypedQuery q = em.createQuery("from Test t join t.translations tt where index(tt)=?1",Test.class).setParameter(1, "pt");

我所有的代码来复制我的问题,这是一个很长的帖子,但它是完整的例子。我可能遗漏的任何信息都可以询问。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>JpaTests</groupId>
    <artifactId>JpaTests</artifactId>
    <version>1.0</version>

    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.1.3.Final</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.9</version>
        </dependency>
    </dependencies>
</project>

持久性.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.connection.username" value="root"/>
            <property name="hibernate.connection.password" value="root"/>
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost/test"/>
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>

            <property name="hibernate.connection.autocommit" value="false"/>
            <property name="hibernate.current_session_context_class" value="thread"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.use_sql_comments" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>
</persistence>

测试.java

import javax.persistence.*;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

@Entity
public class Test implements Serializable {

    @Embeddable
    public static class TestTranslation {
        private String text;

        public TestTranslation() {
        }

        public TestTranslation(String text) {
            this.text = text;
        }

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @ElementCollection(fetch = FetchType.EAGER)
    private Map<String, TestTranslation> translations = new HashMap<String, TestTranslation>();

    @ElementCollection
    private Map<String,String> map1=new HashMap<String, String>();


    public Test() {
    }

    public Test(Map<String, TestTranslation> translationMap) {
        this.translations=translationMap;
    }

    public Test(Map<String, TestTranslation> tr, Map<String, String> map1) {
        this.translations=tr;
        this.map1=map1;
    }

    public long getId() {
        return id;
    }

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

    public Map<String, TestTranslation> getTranslations() {
        return translations;
    }

    public void setTranslations(Map<String, TestTranslation> translations) {
        this.translations = translations;
    }

    public Map<String, String> getMap1() {
        return map1;
    }

    public void setMap1(Map<String, String> map1) {
        this.map1 = map1;
    }
}

主.java

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.Root;
import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("test");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();

        Map<String, Test.TestTranslation> tr = new HashMap<String, Test.TestTranslation>();
        tr.put("pt", new Test.TestTranslation("teste"));
        tr.put("en", new Test.TestTranslation("test"));

        Map<String, String> map1 = new HashMap<String, String>();
        map1.put("pt", "teste");
        map1.put("en", "test");

        Test test = new Test(tr,map1);

        em.persist(test);
        em.getTransaction().commit();


        //got data time to make the query
        em = emf.createEntityManager();
        em.getTransaction().begin();

        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Test> cq = cb.createQuery(Test.class);
        Root<Test> root = cq.from(Test.class);

        //tried a simpler map but it also fails with NullPointerException
        MapJoin<Test, String, String> joinTranslations = root.joinMap("translations");
        //MapJoin<Test, String, String> join = root.joinMap("map1");

        cq = cq.where(cb.equal(joinTranslations.key(), "pt"));
        //cq = cq.where(cb.equal(join.key(), "pt"));

        TypedQuery<Test> q = em.createQuery(cq);
        for (Test itm : q.getResultList()) {
            System.out.println(itm.getId());
            for (Map.Entry<String, Test.TestTranslation> entry : itm.getTranslations().entrySet()) {
                System.out.println(entry.getKey() + ":" + entry.getValue().getText());
            }
        }
        em.getTransaction().commit();
    }
}
4

1 回答 1

1

经过大量搜索,在我的鼻子下方找到了答案:

这个问题jpa criteriabuilder join maps引用了一个错误https://hibernate.onjira.com/browse/HHH-6103最后我注意到修复版本是 4.1.6,在我的 pom.xml 上进行了更改并解决了问题.

原来这是休眠 4.1.3 中的一个错误。

于 2012-09-11T22:03:26.643 回答