Я новичок в Spring-Hibernate, и моя проблема такова: транзакция не сохраняет данные в таблице. Но не бросать никаких исключений. От линии@Transactional: Есть ли способ, с помощью которого спящий режим может продолжать дочернюю транзакцию, когда родительский сбой
Long id = logTransactionFileUpload(fileMetdataBean);
в функции «logClientFile» (в «транзакционного» аннотированный класс класс/услуги, перечисленные ниже), я вижу возвращенного идентификатор, но данные не отображаются в таблице..
F inding является: это вложенные транзакции и откат, как родитель имел исключение из «msgProducer.send (сообщение, jmsConnectInfo)» в классе JobRunnerServiceImpl, в submitJob означает ме- после вставки дБ. Есть ли способ, с помощью которого спящий режим может продолжать дочернюю транзакцию при выходе из строя родителя?
Я не подозреваю, что моя конфигурация с пружиной/спящим режимом, так как сохранение других компонентов работает нормально. Только эта часть является проблемой.
FYI:
, если я включаю (в классе DAO осущ, перечисленных ниже)
//getCurrentSession().flush();
//getCurrentSession().getTransaction().commit();
Затем данные обнаруживаются в table.But этой фиксации и флеш не должно быть там, где используется @transactional.
Мой @Transactional аннотированный класс:
@Service("jobRunnerService")
@Transactional
public class JobRunnerServiceImpl implements JobRunnerService
{
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Autowired
@Qualifier("fileLoggerDao")
private IFileLoggerDAO fileLoggerDAO;
@Autowired
@Qualifier("fileMetaDataDao")
private IGenericDAO<FileMetaDataBean,Long> fileMetaDataDAO;
public void submitJob(String serviceName, String filePath, long clientId, long layoutId, String audienceId,
boolean isCA)
{
Map<String, String> parameters = new HashMap<String, String>();
try
{
..... doing something............
LOG.info("Logging file information in FILE_META_DATA table... ");
String loggedFile = logClientFile(fileName, FACEBOOK_FILE_TYPE, fileExt, clientId, tpList);
..... doing something............
LOG.info(" Submitting job to JMS Q....");
msgProducer.send(message, jmsConnectInfo);
//test code for the receiver to see if sent messages are received by receiver
//WildFlyJmsQueueReceive receiver = new WildFlyJmsQueueReceive();
//receiver.receiveMessagesFromQueue();
}
catch (Exception e)
{
String msg = "Error in JobRunnerServiceImpl.submitJob";
LOG.error(msg,e);
throw new RuntimeException(msg,e);
}
}
private String logClientFile(String fileName, String fileType, String fileExt, long clientId, List<ToolkitPropertyBean> tpList)
{
ApplicationEnvironment enviro;
try
{
..... doing something............
//insert record in FILE_META_DATA table
FileMetaDataBean fileMetdataBean = new FileMetaDataBean(fileId, new Long(fileTypeID), fileName, fbFilePickUpDir +java.nio.file.FileSystems.getDefault().getSeparator()+ currentFile.getName(), receivedDate,new Long(FileUtilities.getRecordCount(currentFile)).longValue(), clientId);
Long id = logTransactionFileUpload(fileMetdataBean);
return null;
}
catch (Exception e)
{
String msg = "Inside JobRunnerServiceImpl.logClientFile - Unable to log client file";
LOG.error(msg,e);
throw new RuntimeException(msg,e);
}
}
private Long logTransactionFileUpload(FileMetaDataBean bean)
{
return (Long)fileMetaDataDAO.save(bean);
}
}
Мой боб:
@Entity
@Table(name="FILE_META_DATA", schema = "OAP_META_OWNER", uniqueConstraints = {
@UniqueConstraint(columnNames = "file_meta_data_id"),
})
//@SequenceGenerator(name="file_meta_seq", sequenceName="file_meta_seq")
public class FileMetaDataBean implements Serializable
{
private long fileMetaDataId;
private Long fileType;
private String fileName;
private String originaFileName;
private Date receivedDt;
private Long recordCount;
private Long clientId;
public FileMetaDataBean(){}
public FileMetaDataBean(long fileMetaDataId, Long fileType, String fileName, String originaFileName, Date receivedDt,
long recordCount, long clientId)
{
super();
this.fileMetaDataId = fileMetaDataId;
this.fileType = fileType;
this.fileName = fileName;
this.originaFileName = originaFileName;
this.receivedDt = receivedDt;
this.recordCount = recordCount;
this.clientId = clientId;
}
@Id
// @GeneratedValue(strategy = GenerationType.AUTO, generator = "file_meta_seq")
@Column(name = "file_meta_data_id", unique = true, nullable = false)
public long getFileMetaDataId()
{
return fileMetaDataId;
}
public void setFileMetaDataId(long fileMetaDataId)
{
this.fileMetaDataId = fileMetaDataId;
}
@Column(name = "file_type_id", unique = false, nullable = false)
public Long getFileType()
{
return fileType;
}
public void setFileType(Long fileType)
{
this.fileType = fileType;
}
@Column(name = "file_name", unique = false, nullable = false)
public String getFileName()
{
return fileName;
}
public void setFileName(String fileName)
{
this.fileName = fileName;
}
@Column(name = "original_file_name", unique = false, nullable = false)
public String getOriginaFileName()
{
return originaFileName;
}
public void setOriginaFileName(String originaFileName)
{
this.originaFileName = originaFileName;
}
@Column(name = "received_dt", unique = false, nullable = false)
public Date getReceivedDt()
{
return receivedDt;
}
public void setReceivedDt(Date receivedDt)
{
this.receivedDt = receivedDt;
}
@Column(name = "record_count", unique = false, nullable = false)
public Long getRecordCount()
{
return recordCount;
}
public void setRecordCount(Long recordCount)
{
this.recordCount = recordCount;
}
@Column(name = "client_id", unique = false, nullable = false)
public Long getClientId()
{
return clientId;
}
public void setClientId(Long clientId)
{
this.clientId = clientId;
}
}
дао интерфейс
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;
public interface IGenericDAO< Entity extends Serializable, ID extends Serializable >
{
Entity getById(ID id);
List<Entity> getAll();
List<Entity> getAll(String contraints);
List<Entity> search(Map<String, Object> parms);
ID save(Entity entity);
void saveOrUpdate(Entity entity);
void update(Entity entity);
void delete(Entity entity);
void deleteById(ID id);
void setSessionFactory(SessionFactory sessionFactory);
void setEntity(final Class clazz);
}
дао осущ:
@SuppressWarnings(value = "unchecked")
public class GenericDAOImpl<Entity extends Serializable, ID extends Serializable>
implements IGenericDAO<Entity, ID> {
protected Class<Entity> clazz;
public GenericDAOImpl(Class<Entity> clazz) {
System.out.println(this.getClass().getSimpleName() + " called");
this.clazz = clazz;
}
@Autowired
@Qualifier("sessionFactory")
protected SessionFactory sessionFactory;
@Override
public Entity getById(ID id) {
System.out.println("GenericHibernateDAO.getById called with id: " + id);
return (Entity) getCurrentSession().get(clazz, id);
}
@Override
public List<Entity> getAll() {
System.out.println("GenericHibernateDAO.getAll called");
return getCurrentSession().createCriteria(clazz.getName()).list();
// return getCurrentSession().createQuery("from " + clazz.getName()).list();
}
@Override
public List<Entity> getAll(String contraints) {
System.out.println("GenericHibernateDAO.getAll called. Constraint : " + contraints);
return getCurrentSession().createQuery("from " + clazz.getName() + " " + contraints).list();
}
@Override
public List search(Map<String, Object> parms) {
Criteria criteria = getCurrentSession().createCriteria(clazz);
for (String field : parms.keySet()) {
criteria.add(Restrictions.ilike(field, parms.get(field)));
}
return criteria.list();
}
@Override
public ID save(Entity entity) {
Serializable id = null;
try
{
id = getCurrentSession().save(entity);
}
catch(RuntimeException e)
{
throw e;
}
// getCurrentSession().flush();
// getCurrentSession().getTransaction().commit();
return (ID)id;
}
@Override
public void saveOrUpdate(Entity entity) {
getCurrentSession().saveOrUpdate(entity);
getCurrentSession().flush();
getCurrentSession().getTransaction().commit();
}
@Override
public void update(Entity entity) {
getCurrentSession().update(entity);
getCurrentSession().flush();
getCurrentSession().getTransaction().commit();
}
@Override
public void delete(Entity entity) {
getCurrentSession().delete(entity);
getCurrentSession().flush();
getCurrentSession().getTransaction().commit();
}
@Override
public void deleteById(ID id) {
delete(getById(id));
}
protected Session getCurrentSession() {
// return sessionFactory.openSession();
return sessionFactory.getCurrentSession();
}
@Override
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public void setEntity(final Class clazz) {
this.clazz = clazz;
}
}
Вы пытались переместить '@ Transactional' с уровня класса на уровень? Ожидаете ли вы, что при завершении выполнения 'logClientFile' должна быть запись в БД (видимая) до завершения метода' submitJob'? У меня также была проблема с тем же вопросом, когда я пытаюсь выполнить длинную задачу в одной транзакции. Вы можете получить 'id' bcoz, запись вставляется в БД, но поскольку ваша транзакция все еще продолжается, вы не можете видеть запись в БД. Вы добавили '@ Transactional' в класс, это означает, что все методы в этом классе находятся в транзакции. Проверьте выполнение БД после завершения выполнения вашей программы. – OO7
Вы правы. Это вложенная транзакция и была отброшена назад, поскольку родитель имел исключение из «msgProducer.send (message, jmsConnectInfo)» в классе JobRunnerServiceImpl, в методе submitJob - после вставки db.Поэтому откат. Интересно, существует ли способ сохранить дочернюю транзакцию, даже если родительский сбой. – Patty
Добавьте аннотацию '@ Transactional' к уровню метода и попробуйте с' распространение'. – OO7