首页 > 解决方案 > 在 Hibernete 多租户环境中,persist() 后无法获取实体 ID

问题描述

在调用实体管理器的persist() 后,我试图获取实体的ID。但是,在调用 persist() 之后,我没有得到 ID。em.refresh() 也失败了。我正在使用 Hibernate 的数据库多租户。在我介绍多租户之前,这一切都很好。

这就是我所拥有的:

public class MyEntity{
@Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Basic(optional = false)
   @Column(name = "ID")
.....
}


@Stateless
public class ActionDAO{
......
@PersistenceContext(unitName = "project-persistence-unit")
   protected EntityManager em;

public void saveEntity(MyEntity q) {
       if (q.getId() == null) {
           em.persist(q);
           System.out.println(q.getID); // expect to get an ID here but i get 0 .
       } else {
           em.merge(q);
       }
 }
}

我已经四处寻找,但找不到解决方案!

多租户类如下:

public class CurrentTenantIdentifierResolverImpl implements CurrentTenantIdentifierResolver {
    @Override
    public String resolveCurrentTenantIdentifier() {
        String tenant = ThreadState.INSTANCE.getTenantId();
        return tenant;
    }

    @Override
    public boolean validateExistingCurrentSessions() {
        return true;
    }
}

public class MultiTenantConnectionProviderImpl extends AbstractMultiTenantConnectionProvider {
    @Override
    protected ConnectionProvider getAnyConnectionProvider() {
        Properties properties = new Properties();
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setUrl("jdbc:mysql://localhost:8889/project1?serverTimezone=UTC");
        ds.setUsername("root");
        ds.setPassword("root");
        DatasourceConnectionProviderImpl d = new DatasourceConnectionProviderImpl();
        d.setDataSource(ds);
        d.configure(properties);
        return (ConnectionProvider) d;
    }

    @Override
    protected ConnectionProvider selectConnectionProvider(String tenantId) {
        Properties properties = new Properties();
        String path = MyConstants.DOCUMENT_ROOT + "/" + tenantId.toUpperCase();
        File file = new File(path + File.separator + "DATABASE.properties");
        if (file.exists()) {
            Properties prop = new Properties();
            try {
                InputStream input = new FileInputStream(path + "/DATABASE.properties");
                prop.load(input);
                DriverManagerDataSource ds = new DriverManagerDataSource();
                ds.setUrl(prop.getProperty("URL"));
                ds.setUsername(prop.getProperty("USERNAME"));
                ds.setPassword(prop.getProperty("PASSWORD"));
                input.close();
                DatasourceConnectionProviderImpl d = new DatasourceConnectionProviderImpl();
                d.setDataSource(ds);
                d.configure(properties);
                return (ConnectionProvider) d;

            } catch (IOException | NullPointerException ex) {
                Logger.getLogger(MultiTenantConnectionProviderImpl.class.getName()).log(Level.SEVERE, null, ex);
                ex.printStackTrace();
            }
        }
        return null;

    }

}

持久性.xml

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="project-persistence-unit" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <!--<jta-data-source>java:/PROJECT-DS</jta-data-source>-->
         <properties>
            <property name="hibernate.jdbc.time_zone" value="UTC"/>
            <property name="hibernate.archive.autodetection" value="class"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
            <property name="hibernate.jdbc.batch_size" value="250"/>
            <property name="hibernate.jdbc.fetch_size" value="500"/> 
            <property name="hibernate.order_inserts" value="true"/>
            <property name="hibernate.order_updates" value="true"/>
            <property name="jboss.entity.manager.jndi.name" value="java:/myprojectEM"/>
            <property name="jboss.entity.manager.factory.jndi.name" value="java:/myprojectEMF"/>
            <property name="hibernate.generate_statistics" value="false"/>
            <property name="hibernate.multi_tenant_connection_provider" value="com.myproject.auxiliary.MultiTenantConnectionProviderImpl"/>
            <property name="hibernate.tenant_identifier_resolver" value="com.myproject.auxiliary.CurrentTenantIdentifierResolverImpl"/>
            <property name="hibernate.multiTenancy" value="DATABASE"/>
            <property name="hibernate.enable_lazy_load_no_trans" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

标签: hibernatejax-rs

解决方案


Update class MultiTenantConnectionProviderImpl to use org.apache.commons.dbcp.BasicDataSource instead of org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl


推荐阅读