2016-02-29 2 views
0

Имея немного удовольствия с формулами, и это сводит меня с ума. У нас есть немного кода для получения объекта по формуле, в базе данных нет ссылки, и это нужно делать во время выполнения, следовательно, использование @Formula. Вот как класс выглядит:Формула спящего режима, не находя имена колонок

@Entity 
@Table(name="T_EMPLOYEE_COMPANY_ASSIGNMENT" 
    ,schema="EXPENSES_MAIN" 
) 

public class EmployeeCompanyAssignment implements java.io.Serializable { 



public EmployeeCompanyAssignment() { 
} 

@EmbeddedId 
@AttributeOverrides({ 
    @AttributeOverride(name="employeeId", [email protected](name="EMPLOYEE_ID", nullable=false, precision=10, scale=0)), 
    @AttributeOverride(name="companyId", [email protected](name="COMPANY_ID", nullable=false, precision=10, scale=0)) }) 
public EmployeeCompanyAssignmentId getId() { 
    return this.id; 
} 
@ManyToOne(fetch=FetchType.LAZY) 
@JoinColumn(name="EMPLOYEE_ID", nullable=false, insertable=false, updatable=false) 
public Employee getEmployee() { 
    return this.employee; 
} 

public void setEmployee(Employee employee) { 
    this.employee = employee; 
} 
@ManyToOne(fetch=FetchType.LAZY) 
@JoinColumn(name="COMPANY_ID", nullable=false, insertable=false, updatable=false) 
public Company getCompany() { 
    return this.company; 
} 

public void setCompany(Company company){ 
    this.company = company; 
} 
@Column(name="DEFAULT_WBS_SAP_CODE", length=24) 
public String getDefaultWbsSapCode() { 
    return this.defaultWbsSapCode; 
} 

public void setDefaultWbsSapCode(String defaultWbsSapCode){ 
    this.defaultWbsSapCode = defaultWbsSapCode; 
} 
@Column(name="DEFAULT_COST_CENTER_SAP_CODE", length=10) 
public String getDefaultCostCenterSapCode() { 
    return this.defaultCostCenterSapCode; 
} 

public void setDefaultCostCenterSapCode(String defaultCostCenterSapCode){ 
    this.defaultCostCenterSapCode = defaultCostCenterSapCode; 
} 
.... 
} 

И формулы устанавливаются таким образом:

@Formula(value = "(SELECT * FROM(" + 
     "Select *" + 
      " from T_COST_CENTER cc" + 
      " where cc.is_blocked_in_sap = 0" + 
       " and cc.is_deleted_in_sap = 0" + 
       " and cc.company_id in" + 
        " (SELECT TECA.COMPANY_ID" + 
         " FROM T_EMPLOYEE_COMPANY_ASSIGNMENT TECA" + 
         " WHERE TECA.EMPLOYEE_ID = EMPLOYEE_ID)" + 
     " and LTRIM(" + 
       "(SELECT *" + 
       " FROM (select TECA.DEFAULT_COST_CENTER_SAP_CODE" + 
         " from T_EMPLOYEE_COMPANY_ASSIGNMENT TECA" + 
         " WHERE TECA.EMPLOYEE_ID = EMPLOYEE_ID)" + 
       " where ROWNUM = 1)" + 
      ", '0') = LTRIM(cc.sap_code, '0')" + 
     " order by cc.sap_code DESC" + 
     ")" + 
     " WHERE ROWNUM = 1" + 
     ")") 
public CostCenter getDefaultCostCenter() { 
    return defaultCostCenter; 
} 
public void setDefaultCostCenter(CostCenter defaultCostCenter) { 
    this.defaultCostCenter = defaultCostCenter ; 
} 

@Formula(value="(" + 
     "SELECT *" + 
      " FROM (Select wbs.*" + 
       " from T_WORK_BREAKDOWN_STRUCTURE wbs" + 
       " LEFT OUTER JOIN T_Company c" + 
        " on wbs.company_id = c.id" + 
       " where wbs.sap_code in (select TECA.DEFAULT_WBS_SAP_CODE" + //We shouldn't have to do this this, but whenever I try to call the field DEFAULT_WBS_SAP_CODE direct in the formula, it complains it can't find it 
             " from T_EMPLOYEE_COMPANY_ASSIGNMENT TECA" + 
             " where TECA.EMPLOYEE_ID = EMPLOYEE_ID)" + 
        " and wbs.is_blocked_in_sap = 0" + 
        " and wbs.is_deleted_in_sap = 0" + 
       " order by wbs.sap_code DESC)" + 
     " WHERE ROWNUM = 1"+ 
     ")") 
public WorkBreakdownStructure getDefaultWbs() { 
    return defaultWbs; 
} 
public void setDefaultWbs(WorkBreakdownStructure defaultWbs) { 
    this.defaultWbs = defaultWbs; 
} 

Теперь первоначально я использовал столбцы DEFAULT_COST_CENTER_SAP_CODE и DEFAULT_WBS_SAP_CODE непосредственно без внутреннего выбора, но получение неверный идентификатор ошибки в обоих этих столбцах, поэтому я подумал, что попытаюсь использовать идентификаторы вместо ссылки, однако это также приводит к недопустимому идентификатору. Вот код SQL, который производит спящий режим:

2016-02-29 09:07:49,810 DEBUG org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:104) [rw] - select employeeco0_.EMPLOYEE_ID as EMPLOYEE2_33_1_, employeeco0_.COMPANY_ID as COMPANY1_34_1_, employeeco0_.EMPLOYEE_ID as EMPLOYEE2_34_1_, employeeco0_.COMPANY_ID as COMPANY1_34_0_, employeeco0_.EMPLOYEE_ID as EMPLOYEE2_34_0_, employeeco0_.DEFAULT_COST_CENTER_SAP_CODE as DEFAULT7_34_0_, employeeco0_.DEFAULT_WBS_SAP_CODE as DEFAULT8_34_0_, (SELECT * FROM(Select * from T_COST_CENTER cc where cc.is_blocked_in_sap = 0 and cc.is_deleted_in_sap = 0 and cc.company_id in (SELECT TECA.COMPANY_ID FROM T_EMPLOYEE_COMPANY_ASSIGNMENT TECA WHERE TECA.EMPLOYEE_ID = employeeco0_.EMPLOYEE_ID) and LTRIM((SELECT * FROM (select TECA.DEFAULT_COST_CENTER_SAP_CODE from T_EMPLOYEE_COMPANY_ASSIGNMENT TECA WHERE TECA.EMPLOYEE_ID = employeeco0_.EMPLOYEE_ID) where ROWNUM = 1), '0') = LTRIM(cc.sap_code, '0') order by cc.sap_code DESC) WHERE ROWNUM = 1) as formula2_0_, (SELECT * FROM (Select wbs.* from T_WORK_BREAKDOWN_STRUCTURE wbs LEFT OUTER JOIN T_Company c on wbs.company_id = c.id where wbs.sap_code in (select TECA.DEFAULT_WBS_SAP_CODE from T_EMPLOYEE_COMPANY_ASSIGNMENT TECA where TECA.EMPLOYEE_ID = employeeco0_.EMPLOYEE_ID) and wbs.is_blocked_in_sap = 0 and wbs.is_deleted_in_sap = 0 order by wbs.sap_code DESC) WHERE ROWNUM = 1) as formula3_0_ from EXPENSES_MAIN.T_EMPLOYEE_COMPANY_ASSIGNMENT employeeco0_ where (employeeco0_.COMPANY_ID in (select c.id from T_COMPANY c where c.is_deleted_in_sap =0)) and employeeco0_.EMPLOYEE_ID=? order by employeeco0_.COMPANY_ID

2016-02-29 09:07:49,811 TRACE org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:83) [rw] - binding parameter [1] as [BIGINT] - 28250

2016-02-29 09:07:49,811 TRACE org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:83) [rw] - binding parameter [1] as [BIGINT] - 28250

2016-02-29 09:07:49,811 TRACE org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:83) [rw] - binding parameter [1] as [BIGINT] - 28250

2016-02-29 09:07:49,817 WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions(SqlExceptionHelper.java:143) [rw] - SQL Error: 904, SQLState: 42000

2016-02-29 09:07:49,817 WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions(SqlExceptionHelper.java:143) [rw] - SQL Error: 904, SQLState: 42000

2016-02-29 09:07:49,817 ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions(SqlExceptionHelper.java:144) [rw] - ORA-00904: "EMPLOYEECO0_"."EMPLOYEE_ID": invalid identifier

2016-02-29 09:07:49,817 ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions(SqlExceptionHelper.java:144) [rw] - ORA-00904: "EMPLOYEECO0_"."EMPLOYEE_ID": invalid identifier

Может ли кто-нибудь увидеть, с чего проблема? Мне все это кажется довольно своеобразным ...

Это делается на среде Oracle SQL и с использованием IntelliJ. Без формул, этот класс работает отлично

EDIT

Я обновил формулу для одной функции и тестирует немного больше, чтобы увидеть, что я могу сделать, у меня это так следующие работы :

@OneToOne 
@JoinColumnsOrFormulas({ 
     @JoinColumnOrFormula([email protected]("(SELECT * FROM (" + 
       "SELECT WBS.ID FROM T_WORK_BREAKDOWN_STRUCTURE WBS" + 
       " LEFT OUTER JOIN T_COMPANY c" + 
       " ON WBS.COMPANY_ID = C.ID" + 
       " WHERE"+ 
       " WBS.IS_BLOCKED_IN_SAP = 0" + 
       " AND WBS.IS_DELETED_IN_SAP = 0" + 
       " ORDER BY WBS.SAP_CODE DESC)" + 
       "WHERE ROWNUM=1)")) 
}) 
public WorkBreakdownStructure getDefaultWbs() { 
    return defaultWbs; 
} 

Однако, как только я добавить эту строку в предложении, где:

WBS.SAP_CODE IN (SELECT TECA.DEFAULT_WBS_SAP_CODE FROM T_EMPLOYEE_COMPANY_ASSIGNMENT TECA WHERE TECA.EMPLOYEE_ID = EMPLOYEE_ID) 

Или это:

WBS.SAP_CODE = DEFAULT_WBS_SAP_CODE 

Он терпит неудачу с недействительным идентификатором (На EMPLOYEE_ID и DEFAULT_WBS_SAP_CODE соответственно), но эти поля используются в коде SQL, который он создает для свойств, которые он заполняет. Тестирование SQL генерируется в базе данных напрямую работает. Сформированный работает SQL код выглядит следующим образом:

select 
    employeeco0_.COMPANY_ID as COMPANY1_34_, 
    employeeco0_.EMPLOYEE_ID as EMPLOYEE2_34_, 
    employeeco0_.DEFAULT_COST_CENTER_SAP_CODE as DEFAULT7_34_, 
    employeeco0_.DEFAULT_WBS_SAP_CODE as DEFAULT8_34_, 
    (SELECT 
     * 
    FROM 
     (SELECT 
      WBS.ID 
     FROM 
      T_WORK_BREAKDOWN_STRUCTURE WBS 
     LEFT OUTER JOIN 
      T_COMPANY c 
       ON WBS.COMPANY_ID = C.ID 
     WHERE 
      WBS.IS_BLOCKED_IN_SAP = 0 
      AND WBS.IS_DELETED_IN_SAP = 0 
     ORDER BY 
      WBS.SAP_CODE DESC) 
    WHERE 
     ROWNUM=1 
    ) as formula9_ 
from 
    EXPENSES_MAIN.T_EMPLOYEE_COMPANY_ASSIGNMENT employeeco0_ 

И тот, который не выглядит так:

select 
    employeeco0_.COMPANY_ID as COMPANY1_34_, 
    employeeco0_.EMPLOYEE_ID as EMPLOYEE2_34_, 
    employeeco0_.DEFAULT_COST_CENTER_SAP_CODE as DEFAULT7_34_, 
    employeeco0_.DEFAULT_WBS_SAP_CODE as DEFAULT8_34_, 
    (SELECT 
     * 
    FROM 
     (SELECT 
      WBS.ID 
     FROM 
      T_WORK_BREAKDOWN_STRUCTURE WBS 
     LEFT OUTER JOIN 
      T_COMPANY c 
       ON WBS.COMPANY_ID = C.ID 
     WHERE 
      WBS.SAP_CODE IN (
       SELECT 
        TECA.DEFAULT_WBS_SAP_CODE 
       FROM 
        T_EMPLOYEE_COMPANY_ASSIGNMENT TECA 
       WHERE 
        TECA.EMPLOYEE_ID = employeeco0_.EMPLOYEE_ID 
      ) 
      AND WBS.IS_BLOCKED_IN_SAP = 0 
      AND WBS.IS_DELETED_IN_SAP = 0 
     ORDER BY 
      WBS.SAP_CODE DESC) 
     WHERE 
      ROWNUM=1) as formula9_ 
    from 
     EXPENSES_MAIN.T_EMPLOYEE_COMPANY_ASSIGNMENT employeeco0_ 

Или это выглядит следующим образом:

select 
    employeeco0_.COMPANY_ID as COMPANY1_34_, 
    employeeco0_.EMPLOYEE_ID as EMPLOYEE2_34_, 
    employeeco0_.DEFAULT_COST_CENTER_SAP_CODE as DEFAULT7_34_, 
    employeeco0_.DEFAULT_WBS_SAP_CODE as DEFAULT8_34_, 
    (SELECT 
     * 
    FROM 
     (SELECT 
      WBS.ID 
     FROM 
      T_WORK_BREAKDOWN_STRUCTURE WBS 
     LEFT OUTER JOIN 
      T_COMPANY c 
       ON WBS.COMPANY_ID = C.ID 
     WHERE 
      WBS.SAP_CODE = employeeco0_.DEFAULT_WBS_SAP_CODE 
      AND WBS.IS_BLOCKED_IN_SAP = 0 
      AND WBS.IS_DELETED_IN_SAP = 0 
     ORDER BY 
      WBS.SAP_CODE DESC) 
    WHERE 
     ROWNUM=1 
    ) as formula9_ 
from 
    EXPENSES_MAIN.T_EMPLOYEE_COMPANY_ASSIGNMENT employeeco0_ 

Но это работает, когда сделано в базе данных (если вы замените employeeeec0_.EMPLOYEE_ID или DEFAULT_WBS_SAP_CODE на действительный идентификатор). Надеемся, что это обновление немного помогает

ответ

0

Проблема была вызвана тем фактом, что Oracle SQL не может ссылаться на столбец, объявленный во внешнем запросе во внутреннем запросе. Я должен переосмыслить и повторить запрос, чтобы мне не нужно ссылаться на поле DEFAULT_WBS_SAP_CODE или EMPLOYEE_ID внутри внутреннего запроса

1

Прежде чем использовать формулу и спящий режим, я попытаюсь выполнить запрос непосредственно в базе данных, чтобы понять, какая часть запроса неверна.

Посмотрев на @Formula, я просто вижу «select *»: вы не можете использовать формулу для возврата полностью управляемого объекта, как с помощью @ManyToOne.

Вы должны использовать @Formula с String или Interger.Выбор в @Formula должен иметь один столбец

Кроме того, формула извлекается с сущностью, она может сильно повлиять на производительность из-за сложности запроса и в 90% случаев она не будет использоваться. Возможно, в вашем случае это может стоить того, чтобы не использовать Формулу

+0

Я обновил код, чтобы теперь он просто возвращал идентификаторы нужного объекта и мог получить он работает до тех пор, пока я не использую никаких свойств из объекта или подзаголовка с свойством от объекта. Что касается использования других вещей, кроме формулы, это невозможно, я рефакторинг устаревшего кода, но не могу изменить базу данных, это поле, которое должно быть выполнено вручную, и должно выполняться через инфраструктуру сущности. – Draken

+0

Это, по-видимому, проблема: http://stackoverflow.com/questions/10092320/reference-parent-query-column-in-subquery-oracle – Draken

Смежные вопросы