В спящем режиме, как можно написать запрос для получения данных с помощью составного ключа? - PullRequest
2 голосов
/ 02 декабря 2011

Здесь у меня есть таблица с именем получение, и ее первичным ключом является составной ключ, связанный с другим классом Receipt_compoundKey с двумя переменными с именами voucher_id и company_id,

Как получить данные из получения с помощьюусловие типа company_id=1;

Квитанция:

@Entity

@Table(name = AMAM_Constants.tb_name.RECEIPT_FROM, catalog = AMAM_Constants.db_name)
public class Receipt implements Serializable {

@Id
private Receipt_CompoundKey id;
@OneToOne
@JoinColumn(name = "FROM_LEDGER")
private Ledger fromLedger;
@Column(name = "VOU_DATE")
private Date voucher_Date;
@Column(name = "TOTAL_AMOUNT")
private double total_amount;
@Column(name = "ACTIVE")
private char active;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = AMAM_Constants.tb_name.RECEIPT_FROM_LINK_TO, joinColumns = {
    @JoinColumn(name = "COMPANY_ID"),
    @JoinColumn(name = "VOUCHER_ID")
}, inverseJoinColumns = {
    @JoinColumn(name = "RECP_TO")})
private List<Receipt_To> recptToList = new ArrayList<Receipt_To>();
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = AMAM_Constants.tb_name.RECEIPT_FROM_LINK_ADJMTS, joinColumns = {
    @JoinColumn(name = "COMPANY_ID"),
    @JoinColumn(name = "VOUCHER_ID")
}, inverseJoinColumns = {
    @JoinColumn(name = "RECPT_ADJS")})
private List<Receipt_Adj> recptAdjments = new ArrayList<Receipt_Adj>();

public List<Receipt_Adj> getRecptAdjments() {
    return recptAdjments;
}

public void setRecptAdjments(List<Receipt_Adj> recptAdjments) {
    this.recptAdjments = recptAdjments;
}

public List<Receipt_To> getRecptToList() {
    return recptToList;
}

public void setRecptToList(List<Receipt_To> recptToList) {
    this.recptToList = recptToList;
}

public char getActive() {
    return active;
}

public void setActive(char active) {
    this.active = active;
}

public double getTotal_amount() {
    return total_amount;
}

public void setTotal_amount(double total_amount) {
    this.total_amount = total_amount;
}

public Ledger getFromLedger() {
    return fromLedger;
}

public void setFromLedger(Ledger fromLedger) {
    this.fromLedger = fromLedger;
}

public Receipt_CompoundKey getId() {
    return id;
}

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

public Date getVoucher_Date() {
    return voucher_Date;
}

public void setVoucher_Date(Date voucher_Date) {
    this.voucher_Date = voucher_Date;
}

}

Receipt_CompoundKey:

@Embeddable
public class Receipt_CompoundKey implements Serializable {

@Column(name = "VOUCHER_ID")
private long voucher_Id;
@Column(name = "COMPANY_ID")
private long company_Id;

public Receipt_CompoundKey() {
}

public Receipt_CompoundKey(long voucher_Id) {
    this.voucher_Id = voucher_Id;
}

public Receipt_CompoundKey(long voucher_Id, long company_Id) {
    this.company_Id = company_Id;
    this.voucher_Id = voucher_Id;
}

public long getCompany_Id() {
    return company_Id;
}

public void setCompany_Id(long company_Id) {
    this.company_Id = company_Id;
}

public long getVoucher_Id() {
    return voucher_Id;
}

public void setVoucher_Id(long voucher_Id) {
    this.voucher_Id = voucher_Id;
}

}

Запрос:

String query = "from Receipt where active='Y' and  id=:id ";
begin();
objList = getSession().createQuery(query).setLong("id", key.getCompany_Id()).setLong("id", key.getVoucher_Id()).list();
commit();

Ответы [ 2 ]

1 голос
/ 02 декабря 2011

Сначала вы должны сделать select, а не просто "from Receipt where active='Y' and id=:id " (я предполагаю, что это несущественная ошибка, но на всякий случай, если это не так):

String query = "
SELECT receipt 
FROM Receipt receipt 
WHERE receipt.id = :yourId "

Для создания запроса я используюEntityManager.Вот пример класса и как он работает для меня.

public class EntityManagerUtil {

    private static EntityManagerFactory entityManagerFactory = null;

    private static final ThreadLocal<EntityManager> entitymanager = 
        new ThreadLocal<EntityManager>();

    private static final ThreadLocal<Map<Class<?>, Set<Serializable>>>collectionFieldNameValues = 
        new ThreadLocal<Map<Class<?>, Set<Serializable>>>();

    public static EntityManagerFactory initializeEntityManagerFactory( String persistenceUnit ) {
        if ( entityManagerFactory == null ) {

            entityManagerFactory = Persistence.createEntityManagerFactory( persistenceUnit );
        }
        return entityManagerFactory;
    }

    public static EntityManager getEntityManager() {

        EntityManager entityManager = entitymanager.get();
        // Create a new EntityManager
        if ( entityManager == null || !entityManager.isOpen()) {
            entityManager = entityManagerFactory.createEntityManager();
            entitymanager.set( entityManager );
        }
        return entityManager;
    }

    public static void close() {
        final EntityManager entityManager = entitymanager.get();
        entitymanager.set( null );
        if ( entityManager != null && entityManager.isOpen()) { 
            entityManager.close();
        }
        if ( entityManagerFactory != null && entityManagerFactory.isOpen()) {
            entityManagerFactory.close();
        }
    } 
}

А в своем классе, для которого вы хотите получить данные, вы сначала инициализируете EntityManagerFactory с помощью модуля персистентности (чтобы, скажем, он назывался ReceiptPersistence).Вот как это будет выглядеть:

EntityManagerUtil.initializeEntityManagerFactory("ReceiptPersistence");
EntityManagerUtil.getEntityManager().getTransaction().begin();
Query getReceiptWithId = EntityManagerUtil.getEntityManager().createQuery(query);
getReceiptWithId.setParameter("yourId", idThatYouWant);

Теперь, когда ваш запрос готов, вы можете получить один результат из него с помощью getSingleResult ():

Receipt receipt = (Receipt) getReceiptWithId.getSingleResult();
EntityManagerUtil.getEntityManager().getTransaction().commit();
EntityManagerUtil.getEntityManager().close();

, если вы сделаете этоПопробуйте / поймать (рекомендуется), вы можете сделать EntityManagerUtil.getEntityManager().getTransaction().rollback(); Это необходимо, когда вы делаете некоторые изменения в БД.

Я использую ThreadLocal, чтобы быть уверенным, что для каждого пользователя будет 1 поток.

1 голос
/ 02 декабря 2011

Вы делаете это, как если бы вы использовали идентификатор из одного столбца:

getSession().createQuery(query).setParameter("id", key);

Вы также можете запросить отдельные значения ключа, но здесь это не нужно:

String query = "select r from Receipt r where r.active = 'Y'"
               + " and id.company_Id = :companyId"
               + " and id.voucher_Id = :voucherId";
objList = getSession().createQuery(query)
                      .setLong("companyId", key.getCompany_Id()) 
                      .setLong("voucherId", key.getVoucher_Id())
                      .list();

Пожалуйста, соблюдайте соглашения об именах Java: voucherId, а не voucher_Id, ReceiptCompoundKey, а не Receipt_CompoundKey и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...